- 工信部備案號 滇ICP備05000110號-1
- 滇公安備案 滇53010302000111
- 增值電信業務經營許可證 B1.B2-20181647、滇B1.B2-20190004
- 云南互聯網協會理事單位
- 安全聯盟認證網站身份V標記
- 域名注冊服務機構許可:滇D3-20230001
- 代理域名注冊服務機構:新網數碼
該文章主要是以案例來講解awk的使用方法,以及延伸到一些實際生產環境中使用(比如統計進程整體cpu或內存負載等)
首先,我們后邊的操作以/tmp/file為例,內容如下:
[root@21yunwei tmp]# cat file ll 34523452345 80 97 70 kk 78979797979 90 90 90 hh 78979879797 60 60 60 jj 23678236876 59 58 57 aa 78987897878 23 34 12
1,awk工作模式
awk 'BEGIN{ print "start"} pattern { commands } END{ print "end"}' file
awk是迭代處理,即一行行的處理。比如我們打印第1個字段結果的處理過程:先取第一行的第一個字段,然后再取第二行的第一個字段。。。一直到處理完整個數據流。:
[root@21yunwei tmp]# cat file |awk '{print $1}' ll kk hh jj aa
2,awk指定多個分隔符
awk默認是以空白為分隔符,如果有其他分隔符,我們需要使用-F’ ‘指定(類似cut -d’ ‘)。
[root@21yunwei /]# cat /etc/passwd | tail -2 |awk -F':' '{print $1}' user19 user20
也可以指定多個分隔符,通過正則[]來匹配,如果多個相同符號,我們可以'[ ]+’來將相同符號認為一個.比如我們修改文件file成如下內容:
[root@21yunwei tmp]# cat file ll:34523452345 80 97 70 kk:78979797979 90 90 90 hh 78979879797 60 60 60 jj 23678236876 59 58 57 aa 78987897878 23 34 12
現在我們要取第二列:
[root@21yunwei tmp]# cat file |awk -F'[ :]' '{print $2}' 34523452345 78979797979 78979879797 23678236876 78987897878
如果我們前邊變成兩個冒號,就不可以這樣寫了,要寫成:
[root@21yunwei tmp]# cat file |awk -F'[ :]+' '{print $2}'
沒有+號,則兩個冒號的無法顯示,認為兩個冒號之前認為是空白。其中多個空白也需要+號。
延伸實際應用,取服務器網卡IP:
[root@web9 tmp]# ifconfig eth0 eth0 Link encap:Ethernet HWaddr 52:54:00:8B:CA:F2 inet addr:192.168.1.9 Bcast:192.168.1.255 Mask:255.255.255.0 inet6 addr: fe80::5054:ff:fe8b:caf2/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
這個寫法有很多,我們只舉例awk,其他方式比如cut也可以獲取。awk獲取IP如下:
[root@21yunwei tmp]# ifconfig eth0 | grep "t a" |awk -F'[ :]+' '{print $4}' 192.168.1.9 [root@21yunwei tmp]# ifconfig eth0 | awk 'NR==2{print $0}' |awk -F'[ :]+' '{print $4}' 192.168.1.9
3,awk內置變量NF講解
NF:每一行的字段數量,每一行的NF值可能不同也可能相同(number of filed)
比如我們查看file的最后一列和倒數第二列:
[root@21yunwei tmp]# cat file |awk '{print $NF,$(NF-1)}' 70 97 90 90 60 60 57 58 12 34
4,awk內置變量NR講解
NR:數據流的行數,number of recoding
值如下:
[root@21yunwei tmp]# awk '{print NR}' file 1 2 3 4 5
舉例我們分別打印第一行、打印2-4行:
[root@21yunwei tmp]# cat file |awk 'NR==1{print $0}' ll 34523452345 80 97 70 [root@21yunwei tmp]# cat file |awk 'NR==2,NR==4{print $0}' kk 78979797979 90 90 90 hh 78979879797 60 60 60 jj 23678236876 59 58 57 [root@21yunwei tmp]# cat file |awk 'NR>1&&NR<5{print $0}' kk 78979797979 90 90 90 hh 78979879797 60 60 60 jj 23678236876 59 58 57 [root@21yunwei tmp]# cat file |awk 'NR!=1&& NR!=5{print $0}' kk 78979797979 90 90 90 hh 78979879797 60 60 60 jj 23678236876 59 58 57
取一行的第一列,取第三行的第二列:
[root@21yunwei tmp]# cat file |awk 'NR==1{print $1} NR==3{print $2}' ll 78979879797
擴展FNR,多個文件同時操作是分別記錄文件行數。
5,awk的pattern介紹
pattern{action}pattern說白了就是一個判斷,后邊接action(動作),即'{}’ 花括號前邊可以加一個判斷,如果為真就執行后邊的,如果是假,則不執行。具體可以參考上邊行數判斷取值。
比如’NR!=1&& NR!=5{print $0}’ ,其中NR!=1&& NR!=5就是pattern,{print $0}就是action
6,awk中BEGIN和END用法
BEGIN和END是一種特殊的模式,BEGIN是在pattern{action}首先執行,END是在pattern{action}執行后執行,即在文本處理前執行和文本執行后。執行效果如下:
[root@21yunwei tmp]# cat file |awk 'BEGIN{print "=====BEGIN======"}{print $0}END{print "=====END======"}' =====BEGIN====== ll 34523452345 80 97 70 kk 78979797979 90 90 90 hh 78979879797 60 60 60 jj 23678236876 59 58 57 aa 78987897878 23 34 12 =====END======
用途:可以用于變量賦值、最后取值、輸出表頭和表尾提示等。
7,awk計算方法
里邊的計算類似C語言的計算方法,可以直接使用。
例1,取3 4 5行的和,取平均數,將取的平均數取整。注意:awk的計算支出小數,如果取整可以int。
[root@21yunwei tmp]# cat file |awk '{print $0,$3+$4+$5,($3+$4+$5)/3,int(($3+$4+$5)/3)}' ll 34523452345 80 97 70 247 82.3333 82 kk 78979797979 90 90 90 270 90 90 hh 78979879797 60 60 60 180 60 60 jj 23678236876 59 58 57 174 58 58 aa 78987897878 23 34 12 69 23 23 另一種寫法: [root@21yunwei tmp]# cat file |awk '{sum=$3+$4+$5;print $0,sum,sum/3,int(sum/3)}' ll 34523452345 80 97 70 247 82.3333 82 kk 78979797979 90 90 90 270 90 90 hh 78979879797 60 60 60 180 60 60 jj 23678236876 59 58 57 174 58 58 aa 78987897878 23 34 12 69 23 23
例2,取第三個字段的總和并去平均值:
[root@21yunwei tmp]# cat file |awk '{total+=$3}END{print total,total/NR}' 312 62.4
延伸生產環境使用,統計httpd占用內存整體使用情況(也可以統計cpu,其他進程一樣):
[root@21yunwei tmp]# ps aux | grep httpd |awk '{total+=$4};END{print total}' 20.8
統計php-fpm的cpu和內存使用:
[root@21yunwei mysqlbak]# ps aux |grep php-fpm|awk '{a+=$3;b+=$4}END{print "cpu:"a,"mem:"b}' cpu:3.1 mem:12.2
8,awk中if用法
用法: awk ‘{if(判斷語句)print ….}’,建議將if判斷加入花括號內部,這樣{}外部就還可以寫入其他的模式判斷語句,當然也可以進行嵌套。
我們取第三列大于等于60的整行輸出:
[root@21yunwei tmp]# cat file |awk '{if($3>=60)print $0}' ll 34523452345 80 97 70 kk 78979797979 90 90 90 hh 78979879797 60 60 60 以上結果等同于: [root@21yunwei tmp]# cat file |awk '$3>=60{print $0}' ll 34523452345 80 97 70 kk 78979797979 90 90 90 hh 78979879797 60 60 60
延伸:我們將/var/log/目錄下大于25K的文件列出(當然find也是可以的):
[root@21yunwei log]# ll |awk '/^-/{if($5>25600){print $0}}' -rw------- 1 root root 328869 9月 2 02:30 cron -rw------- 1 root root 469313 8月 7 03:13 cron-20160807 -rw------- 1 root root 465889 8月 14 03:34 cron-20160814 -rw------- 1 root root 453704 8月 21 03:27 cron-20160821 -rw------- 1 root root 452841 8月 28 03:25 cron-20160828 -rw-r--r--. 1 root root 167384 10月 20 2015 dracut.log-20160101 -rw-r--r--. 1 root root 295504 9月 1 23:57 lastlog -rw------- 1 root root 411506 8月 31 16:50 maillog -rw------- 1 root root 887248 8月 7 03:10 maillog-20160807 -rw------- 1 root root 863595 8月 14 03:30 maillog-20160814 -rw------- 1 root root 810424 8月 21 03:25 maillog-20160821 -rw------- 1 root root 806775 8月 28 03:20 maillog-20160828 -rw------- 1 root root 40093034 9月 2 02:33 messages -rw------- 1 root root 56538021 8月 7 03:13 messages-20160807 -rw------- 1 root root 56686276 8月 14 03:34 messages-20160814 -rw------- 1 root root 56529992 8月 21 03:26 messages-20160821 -rw------- 1 root root 56520983 8月 28 03:25 messages-20160828 -rw------- 1 root root 190881 8月 6 23:05 secure-20160807 -rw------- 1 root root 62891 8月 12 20:56 secure-20160814 -rw-rw-r--. 1 root utmp 392448 9月 1 23:57 wtmp
默認是字節,我們需要換算一下。25K=1014*25
9,awk中變量介紹
awk可以自己定義新變量,類似C語言方法,定義的變量方便我們調用比如:
[root@21yunwei tmp]# cat file|awk '{total+=$NF}END{print total}' 289
比如我們之前統計httpd占用內存百分比,也使用到了變量:
[root@21yunwei tmp]# ps aux | grep httpd |awk '{total+=$4};END{print total}' 20.8
10,awk中for循環使用
awk的for循環,類似C語言中的for循環。舉例如下:
[root@21yunwei tmp]# cat file |awk '{for(i=1;i<NF-2;i++){print $i}}' ll 34523452345 kk 78979797979 hh 78979879797 jj 23678236876 aa 78987897878
一行一行的處理,比如第一行,我們可以知道是i<3,即可i為1 2 ,則打印$1 $2兩個字段。剩下每行也是打印$1 $2兩個字段。
再弄一個取這個file?奇數列:
[root@21yunwei tmp]# cat file |awk '{for(i=1;i<=NF;i+=2){printf $i" "}print a}' ll 80 70 kk 90 90 hh 60 60 jj 59 57 aa 23 12
注意事項:步長+2,printf不換行輸出加空格,可以讓其整行輸出;后邊輸出一個空變量做換行。取偶數列則起始值改成2.
11,awk正則表達式
awk '/^abc/{....}' 以abc開頭 awk '!/^abc/{...}' 不是以abc開頭 awk '/abc/{...}' 包含abc字符串 awk '!/abc/{...}' 不包含abc ~:匹配,可以和上邊的結合使用。
舉例如下:
[root@21yunwei tmp]# cat file |awk '/^kk/{print $0}' kk 78979797979 90 90 90 [root@21yunwei tmp]# cat file |awk '!/^kk/{print $0}' ll 34523452345 80 97 70 hh 78979879797 60 60 60 jj 23678236876 59 58 57 aa 78987897878 23 34 12 [root@21yunwei tmp]# cat file |awk '/6/{print $0}' hh 78979879797 60 60 60 jj 23678236876 59 58 57 [root@21yunwei tmp]# cat file |awk '!/6/{print $0}' ll 34523452345 80 97 70 kk 78979797979 90 90 90 aa 78987897878 23 34 12 [root@21yunwei tmp]# cat file |awk '!/6/&& $1~/kk/{print $0}' kk 78979797979 90 90 90 [root@21yunwei tmp]#
總結:awk是強大的工具,基本可以實現所有需要數據獲取。有些時候grep、find、sed等可以相對實現功能,或其實現不了的功能awk也能實現。原則就是一個,滿足功能需求的前提下什么方便使用什么。
售前咨詢
售后咨詢
備案咨詢
二維碼
TOP