一、什么是awk
awk
是Linux
下的一個(gè)命令,他對(duì)其他命令的輸出,對(duì)文件的處理都十分強(qiáng)大,其實(shí)他更像一門(mén)編程語(yǔ)言,他可以自定義變量,有條件語(yǔ)句,有循環(huán),有數(shù)組,有正則,有函數(shù)等。他讀取輸出,或者文件的方式是一行,一行的讀,根據(jù)你給出的條件進(jìn)行查找,并在找出來(lái)的行中進(jìn)行操作,感覺(jué)他的設(shè)計(jì)思想,真的很簡(jiǎn)單,但是結(jié)合實(shí)際情況,具體操作起來(lái)就沒(méi)有那么簡(jiǎn)單了。他有三種形勢(shì),awk
,gawk
,nawk
,平時(shí)所說(shuō)的awk
其實(shí)就是gawk
。
二、awk命令格式和選項(xiàng)
·2.1 語(yǔ)法形式
awk [options] 'script' var=value file(s)
awk [options] -f scriptfile var=value file(s)
·盡管操作可能會(huì)很復(fù)雜,但語(yǔ)法總是這樣,其中 pattern
表示 awk
在數(shù)據(jù)中查找的內(nèi)容,而 action
是在找到匹配內(nèi)容時(shí)所執(zhí)行的一系列命令。花括號(hào)({}
)不需要在程序中始終出現(xiàn),但它們用于根據(jù)特定的模式對(duì)一系列指令進(jìn)行分組。 pattern
就是要表示的正則表達(dá)式,用斜杠括起來(lái)。
·awk
語(yǔ)言的最基本功能是在文件或者字符串中基于指定規(guī)則瀏覽和抽取信息,awk
抽取信息后,才能進(jìn)行其他文本操作。完整的awk
腳本通常用來(lái)格式化文本文件中的信息。
·通常,awk
是以文件的一行為處理單位的。awk
每接收文件的一行,然后執(zhí)行相應(yīng)的命令,來(lái)處理文本。
·2.2 命令選項(xiàng)
-F fs or --field-separator fs
指定輸入文件折分隔符,fs
是一個(gè)字符串或者是一個(gè)正則表達(dá)式,如-F:
。
-v var=value or --asign var=value
賦值一個(gè)用戶(hù)定義變量。
-f scripfile or --file scriptfile
從腳本文件中讀取awk命令。
-mf nnn and -mr nnn
對(duì)nnn
值設(shè)置內(nèi)在限制,-mf
選項(xiàng)限制分配給nnn
的最大塊數(shù)目;
-mr
選項(xiàng)限制記錄的最大數(shù)目。這兩個(gè)功能是Bell實(shí)驗(yàn)室版awk
的擴(kuò)展功能,在標(biāo)準(zhǔn)awk
中不適用。
-W compact or --compat, -W traditional or --traditional
在兼容模式下運(yùn)行awk
。所以gawk
的行為和標(biāo)準(zhǔn)的awk
完全一樣,所有的awk
擴(kuò)展都被忽略。
-W copyleft or --copyleft, -W copyright or --copyright
打印簡(jiǎn)短的版權(quán)信息。
-W help or --help, -W usage or --usage
打印全部awk
選項(xiàng)和每個(gè)選項(xiàng)的簡(jiǎn)短說(shuō)明。
-W lint or --lint
打印不能向傳統(tǒng)unix
平臺(tái)移植的結(jié)構(gòu)的警告。
-W lint-old or --lint-old
打印關(guān)于不能向傳統(tǒng)unix
平臺(tái)移植的結(jié)構(gòu)的警告。
-W posix
打開(kāi)兼容模式。但有以下限制,不識(shí)別:\x
、函數(shù)關(guān)鍵字、func
、換碼序列以及當(dāng)fs是一個(gè)空格時(shí),將新行作為一個(gè)域分隔符;操作符**
和**=
不能代替^
和^=
;fflush
無(wú)效。
-W re-interval or --re-inerval
允許間隔正則表達(dá)式的使用,參考(grep
中的Posix
字符類(lèi)),如括號(hào)表達(dá)式[[:alpha:]]
。
-W source program-text or --source program-text
使用program-text
作為源代碼,可與-f
命令混用。
-W version or --version
打印bug
報(bào)告信息的版本。
三、awk的正則
匹配符 | 描述 |
---|---|
\Y | 匹配一個(gè)單詞開(kāi)頭或者末尾的空字符串 |
\B | 匹配單詞內(nèi)的空字符串 |
< | 匹配一個(gè)單詞的開(kāi)頭的空字符串,錨定開(kāi)始 |
> | 匹配一個(gè)單詞的末尾的空字符串,錨定末尾 |
\W | 匹配一個(gè)非字母數(shù)字組成的單詞 |
\w | 匹配一個(gè)字母數(shù)字組成的單詞 |
' | 匹配字符串末尾的一個(gè)空字符串 |
\‘ | 匹配字符串開(kāi)頭的一個(gè)空字符串 |
四、awk的函數(shù)
·4.1 字符串函數(shù)
函數(shù)名 | 描述 |
---|---|
sub | 匹配記錄中最大、最靠左邊的子字符串的正則表達(dá)式,并用替換字符串替換這些字符串。如果沒(méi)有指定目標(biāo)字符串就默認(rèn)使用整個(gè)記錄。替換只發(fā)生在第一次匹配的 時(shí)候 |
gsub | 整個(gè)文檔中進(jìn)行匹配 |
index | 返回子字符串第一次被匹配的位置,偏移量從位置1開(kāi)始 |
substr | 返回從位置1開(kāi)始的子字符串,如果指定長(zhǎng)度超過(guò)實(shí)際長(zhǎng)度,就返回整個(gè)字符串 |
split | 可按給定的分隔符把字符串分割為一個(gè)數(shù)組。如果分隔符沒(méi)提供,則按當(dāng)前FS值進(jìn)行分割 |
length | 返回記錄的字符數(shù) |
match | 返回在字符串中正則表達(dá)式位置的索引,如果找不到指定的正則表達(dá)式則返回0。match函數(shù)會(huì)設(shè)置內(nèi)建變量RSTART為字符串中子字符串的開(kāi)始位 置,RLENGTH為到子字符串末尾的字符個(gè)數(shù)。substr可利于這些變量來(lái)截取字符串 |
toupper和tolower | 可用于字符串大小間的轉(zhuǎn)換,該功能只在gawk中有效 |
·4.2 數(shù)學(xué)函數(shù)
函數(shù)名 | 返回值 |
---|---|
atan2(x,y) | y,x 范圍內(nèi)的余切 |
cos(x) | 余弦函數(shù) |
exp(x) | 求 冪 |
int(x) | 取整 |
log(x) | 自然對(duì) 數(shù) |
rand() | 隨機(jī)數(shù) |
sin(x) | 正弦 |
sqrt(x) | 平 方根 |
srand(x) | x是rand()函數(shù)的種子 |
int(x) | 取 整,過(guò)程沒(méi)有舍入 |
rand() | 產(chǎn)生一個(gè)大于等于0而小于1的隨機(jī)數(shù) |
五、入門(mén)實(shí)例
·假設(shè)last -n 5
的輸出如下
[root@www ~]# last -n 5 <==僅取出前五行
root pts/1 192.168.1.100 Tue Feb 10 11:21 still logged in
root pts/1 192.168.1.100 Tue Feb 10 00:46 - 02:28 (01:41)
root pts/1 192.168.1.100 Mon Feb 9 11:41 - 18:30 (06:48)
dmtsai pts/1 192.168.1.100 Mon Feb 9 11:41 - 11:41 (00:00)
root tty1 Fri Sep 5 14:09 - 14:10 (00:01)
·如果只是顯示最近登錄的5個(gè)帳號(hào)
#last -n 5 | awk '{print $1}'
root
root
root
dmtsai
root
·awk
工作流程是這樣的:讀入有'\n'
換行符分割的一條記錄,然后將記錄按指定的域分隔符劃分域,填充域,$0
則表示所有域,$1
表示第一個(gè)域,$n
表示第n
個(gè)域。默認(rèn)域分隔符是"空白鍵" 或[tab]
鍵,所以$1
表示登錄用戶(hù),$3
表示登錄用戶(hù)ip
,以此類(lèi)推。
·如果只是顯示/etc/passwd
的賬戶(hù)
#cat /etc/passwd |awk -F ':' '{print $1}'
root
daemon
bin
sys
·這種是awk+action
的示例,每行都會(huì)執(zhí)行action{print $1}
。
-F
指定域分隔符為':'
。
·如果只是顯示/etc/passwd
的賬戶(hù)和賬戶(hù)對(duì)應(yīng)的shell
,而賬戶(hù)與shell
之間以tab
鍵分割
#cat /etc/passwd |awk -F ':' '{print $1"\t"$7}'
root /bin/bash
daemon /bin/sh
bin /bin/sh
sys /bin/sh
·如果只是顯示/etc/passwd
的賬戶(hù)和賬戶(hù)對(duì)應(yīng)的shell
,而賬戶(hù)與shell
之間以逗號(hào)分割,而且在所有行添加列名name
,shell
,在最后一行添加"blue,/bin/nosh"
。
cat /etc/passwd |awk -F ':' 'BEGIN {print "name,shell"} {print $1","$7} END {print "blue,/bin/nosh"}'
name,shell
root,/bin/bash
daemon,/bin/sh
bin,/bin/sh
sys,/bin/sh
....
blue,/bin/nosh
·awk
工作流程是這樣的:先執(zhí)行BEGING
,然后讀取文件,讀入有/n
換行符分割的一條記錄,然后將記錄按指定的域分隔符劃分域,填充域,$0
則表示所有域,$1
表示第一個(gè)域,$n
表示第n
個(gè)域,隨后開(kāi)始執(zhí)行模式所對(duì)應(yīng)的動(dòng)作action
。接著開(kāi)始讀入第二條記錄······直到所有的記錄都讀完,最后執(zhí)行END
操作。
·搜索/etc/passwd
有root
關(guān)鍵字的所有行
#awk -F: '/root/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
·這種是pattern
的使用示例,匹配了pattern
(這里是root
)的行才會(huì)執(zhí)行action
(沒(méi)有指定action
,默認(rèn)輸出每行的內(nèi)容)。
·搜索支持正則,例如找root
開(kāi)頭的: awk -F: '/^root/' /etc/passwd
·搜索/etc/passwd
有root
關(guān)鍵字的所有行,并顯示對(duì)應(yīng)的shell
# awk -F: '/root/{print $7}' /etc/passwd
/bin/bash
這里指定了action{print $7}
參考文獻(xiàn):
http://man.lupaworld.com/content/manage/ringkee/awk.htm
http://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858470.html
http://www.codeweblog.com/awk命令-awk編程語(yǔ)言詳細(xì)介紹和實(shí)例/