linux之awk
awk,文本處理三劍客之一,它的名稱得自於它的創始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首個字母,它不僅是 linux中也是任何環境中現有的功能最強大的數據處理引擎之一。作為一種強大的語言,它具備了一個完整的語言所應具有的幾乎所有精美特性。
基本格式:awk [options] ‘program‘ file…
program:pattern{action statements;..}
pattern和action:
pattern部分決定動作語句何時觸發及觸發事件 BEGIN,END action statements對數據進行處理,放在{}內指明 print, printf
二 awk語法
第一步:執行BEGIN{action;… }語句塊中的語句
第二步:從文件或標準輸入(stdin)讀取一行,然後執行pattern{ action;… }語句塊,它逐行掃描文件,從第一行到最後一行重復這 個過程,直到文件全部被讀取完畢。
第三步:當讀至輸入流末尾時,執行END{action;…}語句塊
BEGIN語句塊在awk開始從輸入流中讀取行之前被執行,這是一個 可選的語句塊,比如變量初始化、打印輸出表格的表頭等語句通常 可以寫在BEGIN語句塊中 END語句塊在awk從輸入流中讀取完所有的行之後即被執行,比如 打印所有行的分析結果這類信息匯總都是在END語句塊中完成,它 也是一個可選語句塊 pattern語句塊中的通用命令是最重要的部分,也是可選的。如果 沒有提供pattern語句塊,則默認執行{ print },即打印每一個讀取 到的行,awk讀取的每一行都會執行該語句塊
三 awk運算符
四 awk控制語句
控制語句if-else
語法:if(condition){statement;…}[else statement]
if(condition1){statement1}else if(condition2){statement2}
else{statement3}
此語句使用場景:對awk取得的整行或某個字段做條件判斷
舉例:
awk -F:‘{if($3>=1000)print $1,$3}‘ /etc/passwd (小於1000不做處理,所以沒有else)
awk ‘BEGIN{ test=100;if(test>90){print "very good"}else if(test>60){print "good"}else{print "no pass"}}‘
控制語句while
語法:while(condition){statement;...}
條件“真”,進入循環;條件“假”,退出循環
此語句使用場景:對一行內的多個字段逐一類似處理時使用;對數組中的各元素逐一處理時使用
舉例:
awk ‘/^[[:space:]]*linux16/{i=1;while(i<NF){print $i,length($i);i++}}‘ /etc/grub2.cfg
控制語句do-while
語法:do {statement;...}while(condition)
無論真假,至少執行一次循環體
舉例:
awk ‘BEGIN{ sum=0;i=0;do{ sum+=i;i++;}while(i<=100);print sum }‘
控制語句for
語法:for(expr1;expr2;expr3){statement;...}
舉例:
awk ‘/^[[:space:]]*linux16/{for(i=1;i<=NF;i++){print $i,length($i)}}‘ /etc/grub2.cfg
控制語句break和continue
舉例:
awk ‘BEGIN{sum=0;for(i=1;i<=100;i++){if(i==66)break;sum+=i}print sum}‘
awk ‘BEGIN{sum=0;for(i=1;i<=100;i++){if(i%2==0)continue;sum+=i}print sum}‘
awk數組
關聯數組:array[index-expression]
index-expression:
(1)可以使用任意字符串;字符串要使用雙引號括起來
(2)如果某數組元素事先不存在,在引用時,awk會自動創建此元素,並將其值初始化為“空串”
舉例:
weekdays["mon"]="Monday"
awk ‘BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";print weekdays["mon"]}‘
awk函數
數值處理:
rand():返回0和1之間一個隨機數
舉例:
awk ‘BEGIN{srand();for (i=1;i<=10;i++)print int(rand()100) }‘
字符串處理:
ength([s]):返回指定字符串的長度
sub(r,s,[t]):對t字符串進行搜索r表示的模式匹配的內容,並將第一個匹配的內容替換為s
舉例:
echo "2008:08:08 08:08:08" | awk ‘sub(/:/,"-",$1)‘
gsub(r,s,[t]):對t字符串進行搜索r表示的模式匹配的內容,並全部替換為s所表示的內容
舉例:
echo "2008:08:08 08:08:08" | awk ‘gsub(/:/,"-",$0)‘
split(s,array,[r]):以r為分隔符,切割字符串s,並將切割後的結果保存至array所表示的數組中,第一個索引值為1,第二個索引值為2....
舉例:
netstat -tan | awk ‘/^tcp\>/{split($5,ip,":");count[ip[1]]++} END{for (i in count) {print i,count[i]}}‘
五 小練習
1、統計/etc/fstab文件中每個文件系統類型出現的次數
awk ‘/^UUID/{fs[$3]++}END{for(i in fs){print i,fs[i]}}‘ /etc/fstab
說明:
/^UUID/:模式匹配以UUID開頭的行
fs[$3]++:定義fs[]為關聯數組下標是每條記錄的第3個字段,數組的值是出現的次數
for(i in fs){print i,fs[i]}:在每條記錄都處理完後,用for循環遍歷數組,打印下標(文件類型)和數組元素值(文件類型出現的次數)*
2、統計/etc/fstab文件中每個單詞出現的次數
awk ‘{i=1;while(i<=NF){word[$i]++;i++}}END{for(num in word){print num,word[num]}}‘ /etc/fstab
說明:
用while循環處理每條記錄的每個字段,最主要的是每處理完一個字段要把i置為—,這樣每處理完一個記錄,關聯數組被下一個記錄的每個字段重新賦值
3、提取出字符串yd$C@M05MB%9&Bdh7dq+yVixp3vpw中的所有數字
echo "yd$C@M05MB%9&Bdh7dq+yVixp3vpw" | awk ‘gsub(/[^[:digit:]]/," ",$0)‘
說明:
gsub(r,s,[t]):對t字符串進行搜索r表示的模式匹配的內容,並全部替換為s所表示的內容,模式匹配用的是擴展正則表達式
4、解決DOS攻擊生產案例:根據web日誌或者網絡連接數,監控當某個IP並發連接數或者短時間內PV達到100,即調用防火墻命令封掉對應的IP,監控頻率每隔5分鐘。防火墻命令為:iptables -A INPUT -s IP -j REJECT
awk ‘{access[$1]++}END{for(i in access){if(access[i]>=100){print i,access[i]}}}‘ access_log
用腦子學習才能天天向上,加油!
linux之awk