1. 程式人生 > >awk詳解 數組

awk詳解 數組

破解 區塊 init family 習題 pac 表示 pattern 處理

第1章 awk命令基礎

1.1 awk命令執行過程

1、如果BEGIN 區塊存在,awk執行它指定的動作

2awk從輸入文件中讀取一行,稱為一條輸入記錄。如果輸入文件省略,將從標準輸入讀取

3awk將讀入的記錄分割成字段,將第1個字段放入變量$1中,第2個字段放入$2,以此類推。$0表示整條記錄。字段分隔符使用shell環境變量FS或由參數指定。

4、把當前輸入記錄(數據行)依次與每一個awk命令中awk條件比較,看是否匹配,如果相匹配,就執行對應的動作。如果不匹配,就跳過對應的動作,直到比較完所有的awk命令。

5、當一條輸入記錄比較了所有的awk命令後,awk讀取輸入的下一行,繼續重復步驟

34,這個過程一直持續,直到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號碼最後一位數字是15的人的全名

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號碼最後一位數字是15的人的全名

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

前面的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詳解 數組