awk使用總結
1. 什么是awk
awk是Unix/Linux提供的樣式掃描與處理工具,非常擅長處理結構化數據和生成表單。與sed 和grep 很相似,但功能卻超過大于兩者,由于awk具備各種腳本語言的特點,所以也可以把它看做一種腳本語言。本文介紹了awk的使用方法。
2. awk程序設計模型
awk程序由三部分組成,分別為:初始化(處理輸入前做的準備,放在BEGIN塊中),數據處理(處理輸入數據),收尾處理(處理輸入完成后要進行的處理,放到END塊中)。其中,在“數據處理”過程中,指令被寫成一系列模式/動作過程,模式是用于測試輸入行的規則,以確定是否將應用于這些輸入行。
3. awk調用方式
主要有三種調用方式,分別為:
(1) awk 命令行
你可以象使用普通UNIX 命令一樣使用awk,在命令行中你也可以使用awk 程序設計語言,,這種方法一般只用于解決簡單的問題。當然,你也可以在shell script 程序中引用awk 命令行甚至awk 程序腳本。
(2) 使用-f 選項調用awk 程序
awk 允許將一段awk 程序寫入一個文本文件,然后在awk 命令行中用-f 選項調用并執行這段程序。
(3) 利用命令解釋器調用awk 程序
利用UNIX 支持的命令解釋器功能,我們可以將一段awk 程序寫入文本文件,然后在它的第一行加上#!/bin/awk –f.
4. awk語法
與其它 UNIX 命令一樣,awk 擁有自己的語法:
awk [ -F re] [parameter...] ['prog'] [-f progfile][in_file...]
(1) -F re:允許awk 更改其字段分隔符。
(2) parameter:該參數幫助為不同的變量賦值。
(3) ‘prog’:awk 的程序語句段。這個語句段必須用單拓號:’和’括起,以防被shell 解釋。這個程序語句段的標準形式為:’pattern {action}’
其中pattern 參數可以是egrep 正則表達式中的任何一個,它可以使用語法/re/再加上一些樣式匹配技巧構成。與sed 類似,你也可以使用”,”分開兩樣式以選擇某個范圍。action 參數總是被大括號包圍,它由一系列awk 語句組成,各語句之間用”;”分隔。awk 解釋它們,并在pattern 給定的樣式匹配的記錄上執行其操作。你可以省略pattern 和action 之一,但不能兩者同時省略,當省略pattern 時沒有樣式匹配,表示對所有行(記錄)均執行操作,省略action時執行缺省的操作——在標準輸出上顯示。
(4) -f progfile:允許awk 調用并執行progfile 指定有程序文件。progfile 是一個文本文件,它必須符合awk 的語法。
(5) in_file:awk的輸入文件,awk 允許對多個輸入文件進行處理。值得注意的是awk 不修改輸入文件。如果未指定輸入文件,awk 將接受標準輸入,并將結果顯示在標準輸出上。
5. awk腳本編寫
5.1 awk的內置變量
awk中有兩類內置的變量,一類用戶可根據需要改變,主要有:FS:輸入數據的字段分割符,RS:輸入數據的記錄分隔符,OFS:輸輸出數據的字段分割符,ORS:輸出數據的記錄分隔符;另一類是系統自動改變的,如:NF:當前記錄的字段個數,NR:當前記錄編號等。
舉例說明:
awk -F”:” ‘{ print $1 ” ” $3 }’ /etc/passwd #打印passwd中的第1,3個字段
5.2 pattern/action模式
awk程序部分采用了pattern/action模式,即,針對匹配pattern的數據,使用action邏輯進行處理。
舉例說明:
/^$/ {print “This is a blank line!”} #判斷當前是不是空格
$5 ~ /MA/ {print $1 “,” $3} #判斷第5個字段是不是含有“MA”
NF == 3 { print “this particular record has three fields: ” $0 }
5.3 BEGIN和 END
在 awk中兩個特別的表達式,BEGIN和 END,這兩者都可用于 pattern中,提供 BEGIN 和 END 的作用是給程序賦予初始狀態和在程序結束之后執行一些掃尾的工作。任何在 BEGIN 之后列出的操作(在{}內)將在 awk 開始掃描輸入之前執行,而 END 之后列出的操作將在掃描完全部的輸入之后執行。因此,通常使用BEGIN來初始化變量,使用END 來輸出最終結果。
例:累計銷售文件xs 中的銷售金額(假設銷售金額在記錄的第三字段) :
$awk
>’BEGIN { FS=”:”;print “統計銷售金額”;total=0}
>{print $3;total=total+$3;}
>END {printf “銷售金額總計:%.2f”,total}’ sx
5.4 循環語句
Awk中的循環語句與C很相似,包括do…while,for,continue/break,while等
5.5 條件語句
Awk中的條件語句與C相似,但它有更好地支持。
舉例說明:
if(x ~ /[yY](es) ?/) print x #如果x符合pattern “[yY](es) ?”,則打印出來
{ if ( $0 !~ /matchme/ ) { print $1 $3 $4}} #如果$0不包含“matchme”,則打印第1,3,4個字段
5.6 函數
(1) 數學函數
Awk中包含豐富的數學函數,包括:cos(x),sin(x),log(x),….
(2) 字符串函數
Awk中包含豐富的字符串函數,如:
length(x):求字符串x的長度
index(t,s):返回字符串s在字符串t中的位置
match(s,r):正則表達式r在字符串s中出現位置
…
(3) 自定義函數
awk允許自定義函數,語法是:function name(parameter-list) {statements;}
如:
Function insert(STRING, POS, INS) {
before_tmp = substr(STRING, 1, POS)
after_tmp = substr(STRING, POS + 1)
return before_tmp INS after_tmp
}
調用方法:print insert($1, 4, “XX”)
6. Awk與shell混用
因為 awk 可以作為一個 shell 命令使用, 因此 awk 能與 shell 批處理程序很好的融合在一起,這給實現 awk 與 shell 程序的混合編程提供了可能。實現混合編程的關鍵是 awk 與shell script之間的對話, 換言之, 就是awk與shell script之間的信息交流:awk從shell script中獲取所需的信息(通常是變量的值)、在 awk 中執行 shell 命令行、shell script 將命令執行的結果送給 awk處理以及 shell script讀取 awk的執行結果等等。
6.1. awk讀取Shell script程序變量
在awk中我們可以通過“’$變量名’”的方式讀取sell scrpit程序中的變量。
例如:讀取shell scrpit程序中的變量name
下面給出兩種方式:
第一種比較常用的方式:(雙引號和單引號的意義需要明確)
#!/bin/sh
name=’John’
awk ‘{print $1,$2,”‘$name’”}’ myfile
————————————————-
第二種方式:
#!/bin/sh
name=’John’
awk ‘{print $1,$2,myname}’ myname=$name myfile
不過這種方式中,awk自定義變量myname不能在BEGIN中使用。
6.2. 將shell命令的執行結果送給awk處理
作為信息傳送的一種方法,我們可以將一條shell命令的結果通過管道線(|)傳遞給awk處理:
例:示例awk處理shell命令的執行結果
$who -u | awk ‘{printf(“%s正在執行%s\n”,$2,$1)}’
6.3. shell script程序讀awk的執行結果
shell中可以將awk執行結果賦值給shell變量。我們可以用變量名=`awk語句`的形式將awk執行的結果存放入一個shell script變量。當然也可以用管道線的方法將awk執行結果傳遞給shell script程序處理。
例如:找出myfile中帶有fail字符串的行并統計行數,最后打印出格式為:there are (行數) lines
#!/bin/sh
temp=`awk ‘/fail/{print $0}’ myfile |wc -l`
echo “there are $temp lines