Awk是一個文本處理程序,我更愿意將其稱為教官,這樣聽起來更形象。
我喜歡把各種文本的內(nèi)容稱為士兵,而教官負責管理培訓它們。
日志統(tǒng)計
開發(fā)web的人員知道,我們經(jīng)常需要查看nginx的服務(wù)器來統(tǒng)計來訪者的記錄。而awk教官可以很方便幫我們處理好存放在日志中的士兵,可以幫助我們選出最高的士兵,可以幫助我們選出經(jīng)常出操的士兵,可以幫我們選出哪些士兵經(jīng)常在一起。
看下面的一個需求:我們需要看看經(jīng)常訪問網(wǎng)站的有哪些ip,并且把它們的訪問次數(shù)統(tǒng)計出來。初看這個問題似乎很復雜,不過不要擔心,有問題,找教官,我們只要把我們的要求告訴教官,它就會告訴我們把結(jié)果,這很像sql語句,我們只要寫出要獲取的數(shù)據(jù)就行,至于怎么獲取,全部交給數(shù)據(jù)庫自己處理。
我們的awk語句如下:
awk '{sum[$1]++}END{for (ip in sum) print ip,sum[ip]}' access.log|sort -rn -k 2|head
結(jié)果如下
66.98.123.241 4849144.34.223.61 730101.133.226.32 33023.83.246.193 279101.133.140.228 188101.133.147.20 174101.133.224.74 158101.133.224.22 15159.109.210.199 13247.240.89.111 63
我們簡單分析下我們寫的語句
awk這個不用說,就是我們向教官打招呼'{sum[$1]++}END{for (ip in sum) print ip,sum[ip]}'這個單引號包含的就是我們向教官詢問的問題,其中第一個{}表示我們要循環(huán)每一行,然后把ip保存到sum數(shù)組中,第二個{}表示我們要把相同的ip求和統(tǒng)計出來,其中的END表示最后執(zhí)行,當然在第一個{}之前我們也可以有一個BEGIN。access.log是我們要統(tǒng)計的文件,就是告訴教官要統(tǒng)計那個營的士兵sort是linux的排序命令,就是將士兵排序,其中 -rn表示按照身高,降序排列,因為排序還可能按照體重等排序。k 表示我們需要對那列進行排序,因為前面統(tǒng)計的是ip,count,而我們需要按照count進行排序,所以這里寫2head 是linux的頭部預覽命令,一個營有很多士兵,我們直需要選出前面的幾個士兵就可以了,默認它是選出前是個士兵,當然我們也可以使用 head -n 5選擇前5個士兵。工作流程
awk 'BEGIN{ commands } pattern{ commands } END{ commands }'
1、通過關(guān)鍵字 BEGIN 執(zhí)行 BEGIN 塊的內(nèi)容,即 BEGIN 后花括號 {} 的內(nèi)容。
2、完成 BEGIN 塊的執(zhí)行,開始執(zhí)行body塊。
3、讀入有 \n 換行符分割的記錄。
4、將記錄按指定的域分隔符劃分域,填充域,$0 則表示所有域(即一行內(nèi)容),$1 表示第一個域,$n 表示第 n 個域。
5、依次執(zhí)行各 BODY 塊,pattern 部分匹配該行內(nèi)容成功后,才會執(zhí)行 awk-commands 的內(nèi)容。
6、循環(huán)讀取并執(zhí)行各行直到文件結(jié)束,完成body塊執(zhí)行。
7、開始 END 塊執(zhí)行,END 塊可以輸出最終結(jié)果。
強大的功能
從上面的例子我們也能看出來,awk可以向一般語言一樣,也有自己的數(shù)據(jù)結(jié)構(gòu),也有自己的條件和循環(huán)判斷,而且它也可以自己定義函數(shù),可以說我們編程常用的功能,它都有提供。
因此,當我們需要統(tǒng)計一些文本中的內(nèi)容的時候,我們一定不要忘記去找教官awk,它可能不是最好的教官,但是它一定值得你去選擇它。