第1章 awk命令基礎
1.1 awk命令執行過程
1、如果BEGIN 區塊存在,awk執行它指定的動作。 2、awk從輸入文件中讀取一行,稱為一條輸入記錄。如果輸入文件省略,將從標准輸入讀取 3、awk將讀入的記錄分割成字段,將第1個字段放入變量$1中,第2個字段放入$2,以此類推。$0表示整條記錄。字段分隔符使用shell環境變量FS或由參數指定。 4、把當前輸入記錄(數據行)依次與每一個awk命令中awk條件比較,看是否匹配,如果相匹配,就執行對應的動作。如果不匹配,就跳過對應的動作,直到比較完所有的awk命令。 5、當一條輸入記錄比較了所有的awk命令后,awk讀取輸入的下一行,繼續重復步驟3和4,這個過程一直持續,直到awk讀取到文件尾。 6、當awk讀完所有的輸入行后,如果存在END,就執行相應的動作。
1.2 awk中模式與動作
'pattern{action}'
1.2.1 在awk眼中的行與列
field 字段,列
record 記錄,行
1.3 awk默認有一把“菜刀”
空格系列 (單獨的空格,連續的空格,tab鍵)
-F 指定分隔符
-vFS
FS == field sep 每一列的分隔符
OFS ==output field sep 輸出每一列的時候使用的分隔符
1.4 awk的內置變量
變量 |
含義 |
英文全寫 |
FS |
每一列的分隔符 |
field sep |
NF |
每一行有多少列 |
number of field |
OFS |
輸出每一列的時候使用的分隔符 |
output field sep |
NR |
記錄號 行號 |
number of record |
RS |
每一行的分隔符(每一行的結束標記) |
|
$數字 |
取某一列 |
|
$0 |
取出這一行 |
1.4.1 $NF的使用
$NF 表示最后一列,(NF-1)表示倒數第二列,以此類推。
[root@znix ~]# awk -F: '{print NF}' passwd.txt 7 7 …… [root@znix ~]# awk -F: '{print $NF}' passwd.txt /bin/bash /sbin/nologin /sbin/nologin [root@znix ~]# awk -F: '{print $(NF-1)}' passwd.txt /root /bin /sbin
1.5 【練習題】awk如何使用正則?
1) 顯示Xiaoyu的姓氏和ID號碼
2) 顯示所有ID號碼最后一位數字是1或5的人的全名
3) 姓氏是Zhang的人,顯示他的第二次捐款金額及她的名字
4) 顯示Xiaoyu的捐款.每個值時都有以$開頭.如$520$200$135
1.5.1 環境准備
mkdir -p /server/files/ cat >>/server/files/reg.txt<<EOF Zhang Dandan 41117397 :250:100:175 Zhang Xiaoyu 390320151 :155:90:201 Meng Feixue 80042789 :250:60:50 Wu Waiwai 70271111 :250:80:75 Liu Bingbing 41117483 :250:100:175 Wang Xiaoai 3515064655 :50:95:135 Zi Gege 1986787350 :250:168:200 Li Youjiu 918391635 :175:75:300 Lao Nanhai 918391635 :250:100:175 EOF
1.5.1.1 內容釋義:
第一列是姓氏
第二列是名字
第一第二列合起來就是姓名
第三列是對應的ID號碼
最后三列是三次捐款數量
1.5.2 顯示出第二列中包含X 的。
$2~表示第二列所有的內容。 ~表示所有
在這里X比較特殊,是大寫的,awk中區分大小寫。
[root@znix files]# awk '$2~/X/' reg.txt Zhang Xiaoyu 390320151 :155:90:201 Wang Xiaoai 3515064655 :50:95:135
1.5.3 顯示Xiaoyu的姓氏和ID號碼
[root@znix files]# awk '$2~/Xiaoyu/{print $1,$3}' reg.txt Zhang 390320151
1.5.4 顯示所有ID號碼最后一位數字是1或5的人的全名
[root@znix files]# awk '$3~/(1|5)$/{print $1,$2}' reg.txt [root@znix files]# awk '$3~/[15]$/{print $1,$2}' reg.txt Zhang Xiaoyu Wu Waiwai Wang Xiaoai Li Youjiu Lao Nanhai
1.5.5 姓氏是Zhang的人,顯示他的第二次捐款金額及她的名字
先找到,再進行輸出。(NF-1) 表示倒數第二列。
[root@znix files]# awk -F "[ :]+" '$1~/Zhang/{print $2,$(NF-1)}' reg.txt Dandan 100 Xiaoyu 90
1.5.6 顯示Xiaoyu的捐款.每個值時都有以$開頭.如$520$200$135
tr 命令進行替換,格式比較簡單tr "要替換什么" "替換成什么"
[root@znix files]# awk '$2~/Xiaoyu/{print $4}' reg.txt |tr ":" "$" $155$90$201 [root@znix files]# awk '$2~/Xiaoyu/{gsub(/:/,"$",$NF);print $NF}' reg.txt $155$90$201
1.6 awk中的$0是什么鬼?
$0表示文件中整條記錄(行)的內容,在這里加$0 與不加$0 相同。
[root@znix files]# awk '/Zhang/' reg.txt Zhang Dandan 41117397 :250:100:175 Zhang Xiaoyu 390320151 :155:90:201 [root@znix files]# awk '$0~/Zhang/' reg.txt Zhang Dandan 41117397 :250:100:175 Zhang Xiaoyu 390320151 :155:90:201
1.7 awk中的替換
在awk中,可以用來替換的有三個函數:sub gsub gensub
1.7.1 使用gusb 函數進行替換
gsub(r, s [, t])
r /找誰/
s "替換成什么"
[] 替換那個部分的
表示為: gsub(/找誰/,"替換成什么",替換那個部分的)
1.7.2 替換文本中的內容
題目:顯示Xiaoyu的捐款.每個值時都有以$開頭.如$520$200$135
中間使用分號分割 ;
[root@znix files]# awk '{gsub(/:/,"$",$NF);print $0}' reg.txt Zhang Dandan 41117397 $250$100$175 Zhang Xiaoyu 390320151 $155$90$201 Meng Feixue 80042789 $250$60$50 Wu Waiwai 70271111 $250$80$75 Liu Bingbing 41117483 $250$100$175 Wang Xiaoai 3515064655 $50$95$135 Zi Gege 1986787350 $250$168$200 Li Youjiu 918391635 $175$75$300 Lao Nanhai 918391635 $250$100$175
添加上限定條件后,取到的結果會更加的精確。
[root@znix files]# awk '$2~/Xiaoyu/{gsub(/:/,"$",$NF);print $NF}' reg.txt $155$90$201
1.8 【練習題】判斷當前系統上所有用戶的shell是否為可登錄shell(即用戶的shell不是/sbin/nologin),如果是顯示用戶名字
不包含:!,在awk中不包含可以使用! 表示。
$NF 表示這個文件的最后一列
-F 將分隔符指定為:
[root@znix ~]# awk -F: '$NF!~/nologin$/{print $1}' /etc/passwd root sync shutdown halt clsn oldgirl test stu01 stu02 stu03 znix
1.8.1 【對齊】輸出的結果更美觀整齊--column命令
-t -t參數讓他對齊。
[root@znix files]# awk 'BEGIN{print "姓","名"}{print $1,$2}' reg.txt |column -t 姓 名 Zhang Dandan Zhang Xiaoyu Meng Feixue Wu Waiwai Liu Bingbing Wang Xiaoai Zi Gege Li Youjiu Lao Nanhai
第2章 awk中BEGIN 和 END
2.1 怎么把正則表達式作為條件
BEGIN:開始
里面的內容會在awk讀取文件之前運行
在BEGIN里面定義awk的內置變量
END
END{} 里面放入內容,在讀取完文件內容后執行
先計算,在END里面輸出結果
先計算再輸出
2.1.1 【一個栗子】執行完輸出后,再輸出一個“結束”
[root@znix files]# awk '{print $0}END{print "結束"}' reg.txt Zhang Dandan 41117397 :250:100:175 Zhang Xiaoyu 390320151 :155:90:201 Meng Feixue 80042789 :250:60:50 Wu Waiwai 70271111 :250:80:75 Liu Bingbing 41117483 :250:100:175 Wang Xiaoai 3515064655 :50:95:135 Zi Gege 1986787350 :250:168:200 Li Youjiu 918391635 :175:75:300 Lao Nanhai 918391635 :250:100:175 結束
2.2 【企業案例】統計/etc/services文件里面的空行數量
2.2.1 使用awk的END模式
前面的i++先進行計算,再輸出結果。
i=i+1 與i++ 相同。
[root@znix ~]# awk '/^$/{i=i+1}END{print i}' /etc/services 16 [root@znix ~]# awk '/^$/{i++}END{print i}' /etc/services 16
2.2.2 查看i++的執行過程
i++與i=i+1相同。
i=i+$0 累計相加 計算總和
i=i+1 i++ 計數
[root@znix ~]# awk '/^$/{i++;print i}' /etc/services 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
2.2.3 其他方法:
uniq -c uniq 命令把相鄰兩行一樣的合並,-c為統計出現的次數
[root@znix ~]# awk '/^$/' /etc/services|uniq -c 16 [root@znix ~]# awk '/^$/' /etc/services|wc -l 16
2.3 【案例】seq 100 >num.txt ,計算這個文件每一行相加的結果
i=i+$0 累計相加 計算總和
i=i+1 i++ 計數
沒有賦初始值的時候
i++ 先返回0,再加1,第二次調用的時候先返回1,再加1,以此類推
[root@znix ~]# awk '{i=i+$0}END{print i}' num.txt 5050
第3章 awk數組
3.1 數組是用來做什么的?
分類計算,用於統計。
3.1.1 他能夠干些什么?
統計日志文件中 圖片.jpg 出現了多少次
統計日志文件中 圖片.png 出現了多少次
統計更累的信息
3.2 數組詳解---"酒店"
假設我們有一個酒店
酒店<===>hotel 酒店里面有幾個房間110,119,120,114,401這幾個房間。 酒店的110房間<===> hotel[110] 酒店的119房間<===> hotel[119] 酒店的120房間<===> hotel[121]
酒店房間里面入住客人
3.2.1 如何查看房間里住的是哪位客人?
[root@znix files]# awk 'BEGIN{hotel[110]="lidao" ;hotel[119]="tanjiaoshou";hotel[121]="taojin";print hotel[110],hotel[121],hotel[119]}' lidao taojin tanjiaoshou
3.2.2 使用for語句,對酒店進行循環/查房
awk 'BEGIN{hotel[110]="lidao" ;hotel[119]="tanjiaoshou";hotel[121]="taojin"; for(pol in hotel) print pol,hotel[pol] }'
格式:
for(變量 in 數組) 使用變量對酒店進行循環/查房
print pol,hotel[pol] :
pol 得到-房間的號碼
hotel[pol] 哪個酒店的哪個房間
[root@znix files]# awk 'BEGIN{hotel[110]="lidao" ;hotel[119]="tanjiaoshou";hotel[121]="taojin" > for(pol in hotel) > print pol,hotel[pol] > }' 110 lidao 121 taojin 119 tanjiaoshou
3.3 【企業面試題】統計域名訪問次數(去重統計)。處理以下文件內容,將域名取出並根據域名進行計數排序處理:(百度和sohu面試題)
http://www.nmtui.com/index.html http://www.nmtui.com/1.html http://post.nmtui.com/index.html http://mp3.nmtui.com/index.html http://www.nmtui.com/3.html http://post.nmtui.com/2.html
3.3.1 方法一:sort uniq
uniq 命令 把相鄰兩行一樣的合並
[root@znix ~]# awk -F '[/]+' '{print $2}' www.txt |uniq -c 2 www.nmtui.com 1 post.nmtui.com 1 mp3.nmtui.com 1 www.nmtui.com
sort 排序,默認是按照字母的順序
[root@znix ~]# awk -F '[/]+' '{print $2}' www.txt |sort mp3.nmtui.com post.nmtui.com www.nmtui.com www.nmtui.com www.nmtui.com
3.3.2 方法2 awk數組
3.3.2.1 第一步 取出域名
[root@znix ~]# awk -F '[/]+' '{print $2}' www.txt www.nmtui.com www.nmtui.com post.nmtui.com mp3.nmtui.com www.nmtui.com
3.3.2.2 第二步 顯示
; 兩條命令之間用分號分割。
[root@znix ~]# awk -F '/+' '{hotel[$2]++;print hotel["www.nmtui.com"]}' www.txt 1 2 2 2 3
3.3.2.3 第三步 顯示結果
[root@znix ~]# awk -F '/+' '{hotel[$2]++}END{for(pol in hotel)print pol,hotel[pol]}' www.txt mp3.nmtui.com 1 post.nmtui.com 1 www.nmtui.com 3
第4章 課后題目:
兩個文件 secure.zip access.zip
4.1 統計secure文件中誰在破解你的密碼(統計出破解你密碼的ip地址出現的次數)
4.1.1 方法一
[root@znix test]# awk '/Failed/{fa[$(NF-3)]++}END{for(pol in fa)print pol,fa[pol]}' secure-20161219|column -t 218.65.30.126 17163 218.65.30.61 17163 125.16.71.175 4 169.46.38.74 9 183.136.238.78 30 218.2.0.16 10 122.228.238.66 1 ……
4.1.2 方法二
[root@znix test]# awk '/Failed/{print $(NF-3)}' secure-20161219 |sort|uniq -c|sort -n
4.1.3 結果統計
[root@znix test]# awk '/Failed/{fa[$(NF-3)]++}END{for(pol in fa)print pol,fa[pol]}' secure-20161219|column -t|wc -l 88
4.2 統計access.log文件中對ip地址去重並統計重復數
[root@znix test]# awk '{hotel[$1]++}END{for(pol in hotel)print pol,hotel[pol]}' access.log |head -3 101.226.125.115 284 180.154.137.177 516 101.226.125.116 127
4.3 統計access.log文件中網站一共使用了多少流量
[root@znix test]# awk '{i=i+$10}END{print i}' access.log 2478496663