awk詳解 數組
第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讀取輸入的下一行,繼續重復步驟
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)表示倒數第二列,以此類推。
[[email protected] ~]# awk -F: ‘{print NF}‘ passwd.txt
7
7
……
[[email protected] ~]# awk -F: ‘{print $NF}‘ passwd.txt
/bin/bash
/sbin/nologin
/sbin/nologin
[[email protected] ~]# 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中區分大小寫。
[[email protected] files]# awk ‘$2~/X/‘ reg.txt
Zhang Xiaoyu 390320151 :155:90:201
Wang Xiaoai 3515064655 :50:95:135
1.5.3 顯示Xiaoyu的姓氏和ID號碼
[[email protected] files]# awk ‘$2~/Xiaoyu/{print $1,$3}‘ reg.txt
Zhang 390320151
1.5.4 顯示所有ID號碼最後一位數字是1或5的人的全名
[[email protected] files]# awk ‘$3~/(1|5)$/{print $1,$2}‘ reg.txt
[[email protected] 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) 表示倒數第二列。
[[email protected] files]# awk -F "[ :]+" ‘$1~/Zhang/{print $2,$(NF-1)}‘ reg.txt
Dandan 100
Xiaoyu 90
1.5.6 顯示Xiaoyu的捐款.每個值時都有以$開頭.如$520$200$135
tr 命令進行替換,格式比較簡單tr "要替換什麽" "替換成什麽"
[[email protected] files]# awk ‘$2~/Xiaoyu/{print $4}‘ reg.txt |tr ":" "$"
$155$90$201
[[email protected] files]# awk ‘$2~/Xiaoyu/{gsub(/:/,"$",$NF);print $NF}‘ reg.txt
$155$90$201
1.6 awk中的$0是什麽鬼?
$0表示文件中整條記錄(行)的內容,在這裏加$0 與不加$0 相同。
[[email protected] files]# awk ‘/Zhang/‘ reg.txt
Zhang Dandan 41117397 :250:100:175
Zhang Xiaoyu 390320151 :155:90:201
[[email protected] 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
中間使用分號分割 ;
[[email protected] 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
添加上限定條件後,取到的結果會更加的精確。
[[email protected] files]# awk ‘$2~/Xiaoyu/{gsub(/:/,"$",$NF);print $NF}‘ reg.txt
$155$90$201
1.8 【練習題】判斷當前系統上所有用戶的shell是否為可登錄shell(即用戶的shell不是/sbin/nologin),如果是顯示用戶名字
不包含:! ,在awk中不包含可以使用! 表示。
$NF 表示這個文件的最後一列
-F 將分隔符指定為:
[[email protected] ~]# awk -F: ‘$NF!~/nologin$/{print $1}‘ /etc/passwd
root
sync
shutdown
halt
oldboy
oldgirl
test
stu01
stu02
stu03
znix
1.8.1 【對齊】輸出的結果更美觀整齊--column命令
-t -t參數讓他對齊。
[[email protected] 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 【一個栗子】執行完輸出後,再輸出一個“結束”
[[email protected] 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++ 相同。
[[email protected] ~]# awk ‘/^$/{i=i+1}END{print i}‘ /etc/services
16
[[email protected] ~]# awk ‘/^$/{i++}END{print i}‘ /etc/services
16
2.2.2 查看i++的執行過程
i++與i=i+1相同。
i=i+$0 累計相加 計算總和
i=i+1 i++ 計數
[[email protected] ~]# 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為統計出現的次數
[[email protected] ~]# awk ‘/^$/‘ /etc/services|uniq -c
16
[[email protected] ~]# awk ‘/^$/‘ /etc/services|wc -l
16
2.3 【案例】seq 100 >num.txt ,計算這個文件每一行相加的結果
i=i+$0 累計相加 計算總和
i=i+1 i++ 計數
沒有賦初始值的時候
i++ 先返回0,再加1,第二次調用的時候先返回1,再加1,以此類推
[[email protected] ~]# 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 如何查看房間裏住的是哪位客人?
[[email protected] 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] 哪個酒店的哪個房間
[[email protected] 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.etiantian.org/index.html
http://www.etiantian.org/1.html
http://post.etiantian.org/index.html
http://mp3.etiantian.org/index.html
http://www.etiantian.org/3.html
http://post.etiantian.org/2.html
3.3.1 方法一:sort uniq
uniq 命令 把相鄰兩行一樣的合並
[[email protected] ~]# awk -F ‘[/]+‘ ‘{print $2}‘ www.txt |uniq -c
2 www.etiantian.org
1 post.etiantian.org
1 mp3.etiantian.org
1 www.etiantian.org
sort 排序,默認是按照字母的順序
[[email protected] ~]# awk -F ‘[/]+‘ ‘{print $2}‘ www.txt |sort
mp3.etiantian.org
post.etiantian.org
www.etiantian.org
www.etiantian.org
www.etiantian.org
3.3.2 方法2 awk數組
3.3.2.1 第一步 取出域名
[[email protected] ~]# awk -F ‘[/]+‘ ‘{print $2}‘ www.txt
www.etiantian.org
www.etiantian.org
post.etiantian.org
mp3.etiantian.org
www.etiantian.org
3.3.2.2 第二步 顯示
; 兩條命令之間用分號分割。
[[email protected] ~]# awk -F ‘/+‘ ‘{hotel[$2]++;print hotel["www.etiantian.org"]}‘ www.txt
1
2
2
2
3
3.3.2.3 第三步 顯示結果
[[email protected] ~]# awk -F ‘/+‘ ‘{hotel[$2]++}END{for(pol in hotel)print pol,hotel[pol]}‘ www.txt
mp3.etiantian.org 1
post.etiantian.org 1
www.etiantian.org 3
第4章 課後題目:
兩個文件 secure.zip access.zip
4.1 統計secure文件中誰在破解你的密碼(統計出破解你密碼的ip地址出現的次數)
4.1.1 方法一
[[email protected] 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 方法二
[[email protected] test]# awk ‘/Failed/{print $(NF-3)}‘ secure-20161219 |sort|uniq -c|sort -n
4.1.3 結果統計
[[email protected] 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地址去重並統計重復數
[[email protected] 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文件中網站一共使用了多少流量
[[email protected] test]# awk ‘{i=i+$10}END{print i}‘ access.log
2478496663
awk詳解 數組