調(diào)用awk有三種方式調(diào)用awk,第一種是命令行方式,如:
- awk [-F field-separator] 'commands' input-file(s)
awk [-F field-separator] 'commands' input-file(s)
這里,commands是真正的awk命令。上面例子中,-F域分隔符]是可選的,因?yàn)閍 w k使用空格作為缺省的域分隔符,因此如果要瀏覽域間有空格的文本,不必指定這個選項(xiàng),但如果要瀏覽諸如 passwd文件,此文件各域以冒號作為分隔符,則必須指明- F選項(xiàng):
- awk -F: 'commands' input-file
awk -F: 'commands' input-file
第二種方法是將所有a w k命令插入一個文件,并使 a w k程序可執(zhí)行,然后用a w k命令解釋器作為腳本的首行,以便通過鍵入腳本名稱來調(diào)用它。
第三種方式是將所有的awk命令插入一個單獨(dú)文件,然后調(diào)用:
- awk -f awk_script_ file input_file(s)
awk -f awk_script_ file input_file(s)
- f選項(xiàng)指明在文件awk_script_ file中的a w k腳本,input_file(s)是使用awk進(jìn)行瀏覽的文件名。
模式和動作
任何awk語句都由模式和動作組成。在一個awk腳本中可能有許多語句。模式部分決定動作語句何時觸發(fā)及觸發(fā)事件。處理即對數(shù)據(jù)進(jìn)行的操作。如果省略模式部分,動作將時刻保持執(zhí)行狀態(tài)。模式可以是任何條件語句或復(fù)合語句或正則表達(dá)式。模式包括兩個特殊字段BEGIN和END。使用BEGIN語句設(shè)置計數(shù)和打印頭。BEGIN語句使用在任何文本瀏覽動作之前,之后文本瀏覽動作依據(jù)輸入文件開始執(zhí)行。 END語句用來在awk完成文本瀏覽動作后打印輸出文本總數(shù)和結(jié)尾狀態(tài)標(biāo)志。如果不特別指明模式, awk總是匹配或打印行數(shù)。實(shí)際動作在大括號{ }內(nèi)指明。動作大多數(shù)用來打印,但是還有些更長的代碼諸如 if和循環(huán)(looping)語句及循環(huán)退出結(jié)構(gòu)。如果不指明采取動作, awk將打印出所有瀏覽出來的記錄。
域和記錄
awk執(zhí)行時,其瀏覽域標(biāo)記為$1,$2 . . . $n。這種方法稱為域標(biāo)識。使用這些域標(biāo)識將更容易對域進(jìn)行進(jìn)一步處理。使用$1,$3表示參照第1和第3域,注意這里用逗號做域分隔。如果希望打印一個有5個域的記錄的所有域,不必指明 $1,$2,$3,$4 ,$5,可使用$0,意即所有域。awk瀏覽時,到達(dá)一新行,即假定到達(dá)包含域的記錄末尾,然后執(zhí)行新記錄下一行的讀動作,并重新設(shè)置域分隔。注意執(zhí)行時不要混淆符號$和shell提示符$,它們是不同的。
打印所有域的信息
- /home/l/g/tomotoboy >who
- liuzk423 pts/6 Jul 20 08:27 (219.245.104.240)
- tomotoboy pts/16 Aug 7 23:33 (219.221.98.71)
- liuqingaihn pts/21 Aug 7 23:10 (116.29.229.116)
- guise pts/35 Aug 7 21:13 (58.41.162.27)
- uyty pts/38 Aug 7 22:09 (p3213-ipbf803souka.saitama.ocn.ne.jp)
- yagamil pts/46 Aug 7 20:48 (199.40.206.191)
- /home/l/g/tomotoboy >who | awk '{print $0}'
- liuzk423 pts/6 Jul 20 08:27 (219.245.104.240)
- tomotoboy pts/16 Aug 7 23:33 (219.221.98.71)
- liuqingaihn pts/21 Aug 7 23:10 (116.29.229.116)
- guise pts/35 Aug 7 21:13 (58.41.162.27)
- uyty pts/38 Aug 7 22:09 (p3213-ipbf803souka.saitama.ocn.ne.jp)
- yagamil pts/46 Aug 7 20:48 (199.40.206.191)
/home/l/g/tomotoboy >who
liuzk423 pts/6 Jul 20 08:27 (219.245.104.240)
tomotoboy pts/16 Aug 7 23:33 (219.221.98.71)
liuqingaihn pts/21 Aug 7 23:10 (116.29.229.116)
guise pts/35 Aug 7 21:13 (58.41.162.27)
uyty pts/38 Aug 7 22:09 (p3213-ipbf803souka.saitama.ocn.ne.jp)
yagamil pts/46 Aug 7 20:48 (199.40.206.191)
/home/l/g/tomotoboy >who | awk '{print $0}'
liuzk423 pts/6 Jul 20 08:27 (219.245.104.240)
tomotoboy pts/16 Aug 7 23:33 (219.221.98.71)
liuqingaihn pts/21 Aug 7 23:10 (116.29.229.116)
guise pts/35 Aug 7 21:13 (58.41.162.27)
uyty pts/38 Aug 7 22:09 (p3213-ipbf803souka.saitama.ocn.ne.jp)
yagamil pts/46 Aug 7 20:48 (199.40.206.191)
抽取第一域,并打印出來:
- /home/l/g/tomotoboy >who|awk '{print $1}'
- liuzk423
- tomotoboy
- liuqingaihn
- guise
- uyty
- yagamil
/home/l/g/tomotoboy >who|awk '{print $1}'
liuzk423
tomotoboy
liuqingaihn
guise
uyty
yagamil
打印第一域、第三域
- /home/l/g/tomotoboy >who | awk '{print $1"\t"$3}'
- liuzk423 Jul
- tomotoboy Aug
- liuqingaihn Aug
- guise Aug
- uyty Aug
- yagamil Aug
/home/l/g/tomotoboy >who | awk '{print $1"\t"$3}'
liuzk423 Jul
tomotoboy Aug
liuqingaihn Aug
guise Aug
uyty Aug
yagamil Aug
打印信息頭和信息尾
- /home/l/g/tomotoboy >who | awk 'BEGIN {print "--------BEGIN-------\n"} {print $1"\t"$3} END {print "----------END-------"}'
- --------BEGIN-------
-
- liuzk423 Jul
- tomotoboy Aug
- liuqingaihn Aug
- guise Aug
- uyty Aug
- kenhq Aug
- yagamil Aug
- ----------END-------
/home/l/g/tomotoboy >who | awk 'BEGIN {print "--------BEGIN-------\n"} {print $1"\t"$3} END {print "----------END-------"}'
--------BEGIN-------
liuzk423 Jul
tomotoboy Aug
liuqingaihn Aug
guise Aug
uyty Aug
kenhq Aug
yagamil Aug
----------END-------
如果第一個域等于tomotoboy
- /home/l/g/tomotoboy >who | awk '{if ($1~/tomotoboy/) print $0}'
- tomotoboy pts/16 Aug 7 23:33 (219.221.98.71)
/home/l/g/tomotoboy >who | awk '{if ($1~/tomotoboy/) print $0}'
tomotoboy pts/16 Aug 7 23:33 (219.221.98.71)
如果行的域中包含tomotoboy就打印它
- /home/l/g/tomotoboy >who | awk '$0 ~/tomotoboy/'
- tomotoboy pts/16 Aug 7 23:33 (219.221.98.71)
/home/l/g/tomotoboy >who | awk '$0 ~/tomotoboy/'
tomotoboy pts/16 Aug 7 23:33 (219.221.98.71)
不匹配
- /home/l/g/tomotoboy >who | awk '{if ($1!~/tomotoboy/) print $0}'
- liuzk423 pts/6 Jul 20 08:27 (219.245.104.240)
- uyty pts/38 Aug 7 22:09 (p3213-ipbf803souka.saitama.ocn.ne.jp)
- kenhq pts/40 Aug 7 23:46 (116.77.50.7)
- yagamil pts/46 Aug 7 20:48 (199.40.206.191)
-
- /home/l/g/tomotoboy >who | awk '$0 !~/tomotoboy/'
- liuzk423 pts/6 Jul 20 08:27 (219.245.104.240)
- liuqingaihn pts/21 Aug 7 23:54 (116.29.229.116)
- uyty pts/38 Aug 7 22:09 (p3213-ipbf803souka.saitama.ocn.ne.jp)
- kenhq pts/40 Aug 7 23:46 (116.77.50.7)
- yagamil pts/46 Aug 7 20:48 (199.40.206.191)
/home/l/g/tomotoboy >who | awk '{if ($1!~/tomotoboy/) print $0}'
liuzk423 pts/6 Jul 20 08:27 (219.245.104.240)
uyty pts/38 Aug 7 22:09 (p3213-ipbf803souka.saitama.ocn.ne.jp)
kenhq pts/40 Aug 7 23:46 (116.77.50.7)
yagamil pts/46 Aug 7 20:48 (199.40.206.191)
/home/l/g/tomotoboy >who | awk '$0 !~/tomotoboy/'
liuzk423 pts/6 Jul 20 08:27 (219.245.104.240)
liuqingaihn pts/21 Aug 7 23:54 (116.29.229.116)
uyty pts/38 Aug 7 22:09 (p3213-ipbf803souka.saitama.ocn.ne.jp)
kenhq pts/40 Aug 7 23:46 (116.77.50.7)
yagamil pts/46 Aug 7 20:48 (199.40.206.191)
行首
打印行首包含to的行
- /home/l/g/tomotoboy >who | awk '/^to/'
- tomotoboy pts/16 Aug 7 23:33 (219.221.98.71)
/home/l/g/tomotoboy >who | awk '/^to/'
tomotoboy pts/16 Aug 7 23:33 (219.221.98.71)
AND
打印第一域?yàn)閠omotoboy,第三域?yàn)锳ug的行
- /home/l/g/tomotoboy >who | awk '{if ($1=/tomotoboy/ && $2=/Aug/) print $0}'
- awk: syntax error near line 1
- awk: illegal statement near line 1
- /home/l/g/tomotoboy >who | awk '{if ($1~/tomotoboy/ && $3~/Aug/) print $0}'
- tomotoboy pts/16 Aug 7 23:33 (219.221.98.71)
/home/l/g/tomotoboy >who | awk '{if ($1=/tomotoboy/ && $2=/Aug/) print $0}'
awk: syntax error near line 1
awk: illegal statement near line 1
/home/l/g/tomotoboy >who | awk '{if ($1~/tomotoboy/ && $3~/Aug/) print $0}'
tomotoboy pts/16 Aug 7 23:33 (219.221.98.71)
注意區(qū)分“=”與“==”,獲得兩種截然不同的結(jié)果
- /home/l/g/tomotoboy >who | awk '{if ($1="tomotoboy" && $3="Aug") print $0}'
- tomotoboy pts/6 Aug 20 08:27 (219.245.104.240)
- tomotoboy pts/16 Aug 7 23:33 (219.221.98.71)
- tomotoboy pts/21 Aug 8 00:05 (116.29.229.116)
- tomotoboy pts/35 Aug 8 00:05 (116.29.229.116)
- tomotoboy pts/38 Aug 7 22:09 (p3213-ipbf803souka.saitama.ocn.ne.jp)
- tomotoboy pts/40 Aug 7 23:46 (116.77.50.7)
- tomotoboy pts/46 Aug 7 20:48 (199.40.206.191)
/home/l/g/tomotoboy >who | awk '{if ($1="tomotoboy" && $3="Aug") print $0}'
tomotoboy pts/6 Aug 20 08:27 (219.245.104.240)
tomotoboy pts/16 Aug 7 23:33 (219.221.98.71)
tomotoboy pts/21 Aug 8 00:05 (116.29.229.116)
tomotoboy pts/35 Aug 8 00:05 (116.29.229.116)
tomotoboy pts/38 Aug 7 22:09 (p3213-ipbf803souka.saitama.ocn.ne.jp)
tomotoboy pts/40 Aug 7 23:46 (116.77.50.7)
tomotoboy pts/46 Aug 7 20:48 (199.40.206.191)
- /home/l/g/tomotoboy >who | awk '{if ($1=="tomotoboy" && $3=="Aug") print $0}'
- tomotoboy pts/16 Aug 7 23:33 (219.221.98.71)
/home/l/g/tomotoboy >who | awk '{if ($1=="tomotoboy" && $3=="Aug") print $0}'
tomotoboy pts/16 Aug 7 23:33 (219.221.98.71)
awk內(nèi)置變量
- /home/l/g/tomotoboy >who|awk '{print NF,NR,$0}'
- 6 1 liuzk423 pts/6 Jul 20 08:27 (219.245.104.240)
- 6 2 tomotoboy pts/16 Aug 7 23:33 (219.221.98.71)
- 6 3 liuqingaihn pts/21 Aug 8 00:05 (116.29.229.116)
- 6 4 liuqingaihn pts/35 Aug 8 00:05 (116.29.229.116)
- 6 5 uyty pts/38 Aug 7 22:09 (p3213-ipbf803souka.saitama.ocn.ne.jp)
- 6 6 kenhq pts/40 Aug 7 23:46 (116.77.50.7)
- 6 7 yagamil pts/46 Aug 7 20:48 (199.40.206.191)
/home/l/g/tomotoboy >who|awk '{print NF,NR,$0}'
6 1 liuzk423 pts/6 Jul 20 08:27 (219.245.104.240)
6 2 tomotoboy pts/16 Aug 7 23:33 (219.221.98.71)
6 3 liuqingaihn pts/21 Aug 8 00:05 (116.29.229.116)
6 4 liuqingaihn pts/35 Aug 8 00:05 (116.29.229.116)
6 5 uyty pts/38 Aug 7 22:09 (p3213-ipbf803souka.saitama.ocn.ne.jp)
6 6 kenhq pts/40 Aug 7 23:46 (116.77.50.7)
6 7 yagamil pts/46 Aug 7 20:48 (199.40.206.191)
awk內(nèi)置字符串函數(shù)
awk內(nèi)置字符串函數(shù),awk又很多字符處理函數(shù),這里以length為例
- /home/l/g/tomotoboy >who| awk '{print length($1)" "$1}'
- 8 liuzk423
- 9 tomotoboy
- 11 liuqingaihn
- 11 liuqingaihn
- 5 kenhq
- 7 yagamil
/home/l/g/tomotoboy >who| awk '{print length($1)" "$1}'
8 liuzk423
9 tomotoboy
11 liuqingaihn
11 liuqingaihn
5 kenhq
7 yagamil
如果第一域的長度大于7就輸出
- /home/l/g/tomotoboy >who| awk '{if(length($1)>7) print length($1)" "$1}'
- 8 liuzk423
- 9 tomotoboy
- 11 liuqingaihn
- 11 liuqingaihn
/home/l/g/tomotoboy >who| awk '{if(length($1)>7) print length($1)" "$1}'
8 liuzk423
9 tomotoboy
11 liuqingaihn
11 liuqingaihn
字符串屏蔽序列
使用字符串或正則表達(dá)式時,有時需要在輸出中加入一新行或查詢一元字符。打印一新行時,(新行為字符\n) ,給出其屏蔽序列,以不失其特殊含義,用法為在字符串前加入反斜線。例如使用\n強(qiáng)迫打印一新行。如果使用正則表達(dá)式,查詢花括號({ }) ,在字符前加反斜線,如/ \ { /,將在awk中失掉其特殊含義。
- \b 退格鍵 \t tab鍵
- \f 走紙換頁 \ddd 八進(jìn)制值
- \n 新行 \c 任意其他特殊字符,例如\\為反斜線符號
- \r 回車鍵
- /home/l/g/tomotoboy >who |awk '{print $1"\t""\t"$2"\n"}'
- liuzk423 pts/6
-
- tomotoboy pts/16
-
- liuqingaihn pts/21
-
- liuqingaihn pts/35
-
- kenhq pts/40
-
- yagamil pts/46
\b 退格鍵 \t tab鍵
\f 走紙換頁 \ddd 八進(jìn)制值
\n 新行 \c 任意其他特殊字符,例如\\為反斜線符號
\r 回車鍵
/home/l/g/tomotoboy >who |awk '{print $1"\t""\t"$2"\n"}'
liuzk423 pts/6
tomotoboy pts/16
liuqingaihn pts/21
liuqingaihn pts/35
kenhq pts/40
yagamil pts/46
printf
printf修飾符,prinf基本域C語言的printf相同下面開始舉例
- /home/l/g/tomotoboy >echo "65" |awk '{printf "%c\n",$0}'
- A
- /home/l/g/tomotoboy >echo "65" |awk '{printf "%d\n",$0}'
- 65
- /home/l/g/tomotoboy >echo "65" |awk '{printf "%c\t\t%d\n",$0,$0}'
- A 65
/home/l/g/tomotoboy >echo "65" |awk '{printf "%c\n",$0}'
A
/home/l/g/tomotoboy >echo "65" |awk '{printf "%d\n",$0}'
65
/home/l/g/tomotoboy >echo "65" |awk '{printf "%c\t\t%d\n",$0,$0}'
A 65
awk數(shù)組
- /home/l/g/tomotoboy >awk 'BEGIN {print split("123#456#789",myarray,"#")}'
- 3
/home/l/g/tomotoboy >awk 'BEGIN {print split("123#456#789",myarray,"#")}'
3
在上面的例子中,split返回數(shù)組myarray下標(biāo)數(shù)。實(shí)際上myarray數(shù)組為:
myarray[1]=123
myarray[2]=456
myarray[3]=789
數(shù)組使用前,不必定義,也不必指定數(shù)組元素個數(shù)。經(jīng)常使用循環(huán)來訪問數(shù)組。下面是一種循環(huán)類型的基本結(jié)構(gòu):
For (element in array) print array[element]
對于記錄“123#456#789” ,先使用split函數(shù)劃分它,再使用循環(huán)打印各數(shù)組元素。操作腳本如下:
- #!/bin/awk -f
- #name: arraytest.awk
- #pprint out am array
- BEGIN{
- record="123#456#789";
- split(record,myarray,"#")}
- END { for (i in myarray) {print myarray[i]}}
#!/bin/awk -f
#name: arraytest.awk
#pprint out am array
BEGIN{
record="123#456#789";
split(record,myarray,"#")}
END { for (i in myarray) {print myarray[i]}}
要運(yùn)行腳本,使用/dev/null作為輸入文件。
- /home/l/g/tomotoboy >arraytest.awk /dev/null
- 456
- 789
- 123
/home/l/g/tomotoboy >arraytest.awk /dev/null
456
789
123
小結(jié)
awk語言學(xué)起來可能有些復(fù)雜,但使用它來編寫一行命令或小腳本并不太難。awk是shell編程的一個重要工具。在shell命令或編程中,雖然可以使用awk強(qiáng)大的文本處理能力,但是并不要求你成為這方面的專家