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讀取輸入的下一行,繼續重復步驟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號碼最后一位數字是15的人的全名

[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章 awkBEGIN 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 使用awkEND模式

前面的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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM