awk '/REG/{action} ' file /REG/為正則表達式,可以將$0 ($0代表每一行)中,滿足條件的記錄送入到:action 進行處理 [root@Gin scripts]# awk '/root/{print $0}' passwd ##匹配所有包含root的行 root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin [root@Gin scripts]# awk -F: '$5~/root/{print $0}' passwd ## 以分號作為分隔符,匹配第5個字段是root的行 root:x:0:0:root:/root:/bin/bash
布爾表達式 awk '布爾表達式{action}' file 僅當對前面的布爾表達式求值為真時, awk 才執行代碼塊。 [root@Gin scripts]# awk -F: '$1=="root"{print $0}' passwd root:x:0:0:root:/root:/bin/bash [root@Gin scripts]# awk -F: '($1=="root")&&($5=="root") {print $0}' passwd root:x:0:0:root:/root:/bin/bash
awk 的 if、循環和數組
[root@zhangchao ~]# cat zc.log root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin [root@zhangchao ~]# cat awk.txt #!/bin/awk BEGIN { FS=":" } { if($1=="root") { print "Yes" } else if($1=="bar") { print "No" } else { print "Defailed" } } [root@zhangchao ~]# awk -f awk.txt zc.log Yes Defailed
使用 if 語句還可以將代碼: 1 ! /matchme/ { print $1 $3 $4 } 轉換成: { if ( $0 !~ /matchme/ ) { print $1 $3 $4 } } 循環結構 我們已經看到了 awk 的 while 循環結構,它等同於相應的 C 語言 while 循環。 awk 還有"do...while"循環,它在代碼塊結尾處對條件求值,而不像標准 while 循環那樣在開始處求值。 它類似於其它語言中的"repeat...until"循環。以下是一個示例: do...while 示例 { count=1do { print "I get printed at least once no matter what" } while ( count !=1 ) } 與一般的 while 循環不同,由於在代碼塊之后對條件求值, "do...while"循環永遠都至少執行一次。換句話說,當第一次遇到普通 while 循環時,如果條件為假,將永遠不執行該循環。 for 循環 awk 允許創建 for 循環,它就象 while 循環,也等同於 C 語言的 for 循環: for ( initial assignment; comparison; increment ) { code block } 以下是一個簡短示例: for ( x=1;x<=4;x++ ) { print "iteration", x } 此段代碼將打印: iteration1 iteration2 iteration3 iteration4 break 和 continue 此外,如同 C 語言一樣, awk 提供了 break 和 continue 語句。使用這些語句可以更好地控制 awk 的循環結構。以下是迫切需要 break 語句的代碼片斷: while 死循環 while (1) { print "forever and ever..." } while 死循環 1 永遠代表是真,這個 while 循環將永遠運行下去。 以下是一個只執行十次的循環: #break 語句示例 x=1 while(1) { print "iteration", x if ( x==10 ) { break } x++ } 這里, break 語句用於“逃出”最深層的循環。 "break"使循環立即終止,並繼續執行循環代碼塊后面的語句。 continue 語句補充了 break,其作用如下: x=1while (1) { if ( x==4 ) { x++ continue } print "iteration", x if ( x>20 ) { break } x++ } 這段代碼打印"iteration1"到"iteration21", "iteration4"除外。如果迭代等於 4,則增加 x並調用 continue 語句,該語句立即使 awk 開始執行下一個循環迭代,而不執行代碼塊的其余部分。如同 break 一樣, continue 語句適合各種 awk 迭代循環。在 for 循環主體中使用時, continue 將使循環控制變量自動增加。以下是一個等價循環: for ( x=1;x<=21;x++ ) { if ( x==4 ) { continue } print "iteration", x } 在while 循環中時,在調用 continue 之前沒有必要增加 x,因為 for 循環會自動增加 x。
數組
for…in 輸出,因為數組是關聯數組,默認是無序的。所以通過 for…in 得到是無序的數組。如果需要得到有序數組,需要通過下標獲得。
[root@zhangchao ~]# cat ws.txt I am Zhang Chao, I am from Num 20. [root@zhangchao ~]# cat awk.txt #!/bin/awk { A[1]="beijing" A[2]="shanghai" A["three"]="shenzhen" A["4"]="guangzhou" for(a in A){ print A[a] } print "\n\n" print A[1] print A[2] print A["three"] print A["4"] } [root@zhangchao ~]# awk -f awk.txt ws.txt guangzhou shenzhen beijing shanghai beijing shanghai shenzhen guangzhou
awk -F: '{print NF}' /etc/passwd //顯示每行有多少字段;顯示每行的字段數量; awk -F: '{print $NF}' /etc/passwd //將每行第NF個字段的值打印出來;將每行最后一個字段的內容打印出來
s是數組,$NF是s數組的下標,s[$NF]是數組元素(類似於s[2]);只不過下標可以是字符串; /^tcp/匹配沒有tcp的行; ++s[$NF]數組元素加1; [root@zhangchao ~]# netstat -an|awk '/^tcp/{++s[$NF];print $NF,s[$NF]}END{for(a in s)print a,s[a]}' LISTEN 1 LISTEN 2 LISTEN 3 LISTEN 4 ESTABLISHED 1 LISTEN 5 LISTEN 6 LISTEN 7 LISTEN 7 ESTABLISHED 1
字符串函數的應用 替換 awk 'BEGIN{info="this is a test2010test!";gsub(/[0-9]+/,"!",info);print info}' this is a test!test! 在 info 中查找滿足正則表達式, /[0-9]+/ 用”!”替換,並且替換后的值,賦值給 info 未 給 info 值,默認是$0 查找 awk 'BEGIN{info="this is a test2010test!";print index(info,"test")?"ok":"no found";}' ok #未找到,返回 0 匹配查找 awk 'BEGIN{info="this is a test2010test!";print match(info,/[0-9]+/)?"ok":"no found";}' ok #如果查找到數字則匹配成功返回 ok,否則失敗,返回未找到 截取 awk 'BEGIN{info="this is a test2010test!";print substr(info,4,10);}' s is a tes #從第 4 個 字符開始,截取 10 個長度字符串 分割 awk 'BEGIN{info="this is a test";split(info,tA," ");print length(tA);for(k in tA){print k,tA[k];}}' 4 4 test 1 this 2 is 3 a #分割 info,動態創建數組 tA,awk for …in 循環,是一個無序的循環。 並不是從數組下標 1…n 開始