AWK基礎講解筆記

目錄

awk課程總結... 1

第1章 awk基礎入門... 1

1.1 awk基礎入門... 1

1.2 awk簡介... 1

1.2.1 一種名字怪異的語言... 1

1.2.2 模式掃描和處理... 1

1.3 學過awk可以掌握的內容... 1

1.4 awk命令... 1

1.5模式及pattern,可以類似理解成sed的模式匹配,可以由表達式組成,也可以是倆個正斜槓之間的正則表達式,比如:NR==1 ,這就是模式,可以理解爲一個條件。... 2

1.6動作即action,是由在大括號裏面的一條或者多條語句組成,語句之間使用分號隔開,如下awk使用格式... 2

1.7 awk執行過程... 2

1.8 接下來說倆個新概念:記錄和字段,這裏爲了方便理解可以把記錄當做行記錄===行,字段相當於列,字段===列。... 3

1.9 awk記錄分隔符 -RS. 3

1.9.1 awk默認情況下每一行都是一個記錄... 3

1.9.2 RS即record separator輸入數據記錄分隔符,每一行是怎麼來的,表示每個記錄輸入的時候的分隔符,即行與行之間如何分割。... 3

1.9.3 NR即number of record 記錄行號,表示當前正在處理的行的號碼... 5

1.9.4 ORS即output record separator 輸出記錄分隔符。... 5

1.9.5 awk使用內置變量RS來存放輸入記錄分隔符,RS表示的是輸入的記錄分隔符,這個值可以通過BEGIN模塊重新定義修改。... 5

1.10 思路... 5

1.11 awk記錄知識小結... 6

1.11.1 NR存放着每個記錄的號(行號),讀取新行時候會自動加1(+1)... 6

1.11.2 RS是輸入數據的記錄的分隔符,簡單理解就是可以指定每個記錄的結尾標緻... 6

1.11.3 RS作用就是表示一個記錄的結束... 6

1.11.4 當我們修改了RS的值,最好配合NR來查看變化,也就是修改了RS的值通過NR查看結果,調試awk程序。... 6

1.11.5 ORS輸出數據的記錄的分隔符... 6

1.12 awk學習技巧一則... 6

1.13 字段(字段)... 6

1.14 FS. 7

1.15 說明:... 7

1.16 ORS與OFS簡介... 8

1.16.1 利用OFS調換ETCpasswd位置... 8

1.17 awk都有哪幾種模式... 9

1.17.1 正則表達式作爲模式... 9

1.17.2 比較表達式作爲模式... 9

1.17.3 範圍模式... 9

1.17.4 特殊模式BEGIN和END.. 9

1.18 awk也支持大量的正則表達式,大部分與sed的元字符類似,而且正則表達式是玩轉三劍客的必備工具,... 9

1.19 說明:... 10

1.20 awk注意事項說明:... 10

1.21 awk運算符... 10

第2章 awk特殊模式與END模式... 11

2.1 BEGIN模塊... 11

2.2 命令行 -F本質就是修改的FS變量... 11

2.2.1 第二個作用,在讀取文件之前輸出些提示性信息,表頭。... 11

2.3 awk中的變量的概念簡介... 12

2.4 NEGIN模式說明... 12

2.5 END模塊說明... 12

2.6 awk編程思想... 12

2.6.1 先處理,最後在END模式輸出... 12

2.6.2 {print NF ,$0} boby 模塊處理,處理完畢後... 12

2.6.3 END{print"end of file"} 輸出一個結果... 12

2.7 awk調試技巧:... 12

2.8 幾種常用的運算表達式... 12

2.9 awk中的動作... 13

2.10 awk模式與動作小結... 13

2.11 awk執行過程文字版... 13

第3章 awk數組... 14

3.1 圖片-數組-酒店... 14

3.2 awk數組小結... 15

3.3 這個不知道起什麼名... 15

3.4 企業面試題數組題分解執行過程... 16

第4章練習題... 16

4.1 測試文件... 16

4.1.1 顯示姓Zhang的人的第二次捐款金額及她的名字... 16

4.1.2 顯示Xiaoyu的名字和ID號碼... 17

4.1.3 顯示所有以41開頭的ID號碼的人的全名和ID號碼... 17

4.1.4 顯示所有以一個D或X開頭的人名全名... 17

4.1.5 顯示所有ID號碼最後一位數字是1或5的人的全名... 17

4.1.6 顯示Xiaoyu的捐款.每個值時都有以$開頭.如$520$200$135. 18

4.2 正則表達式部分的疑問... 20

4.3 匹配除了含有oldboy的其他行... 20

4.3.1 測試文件... 20

4.3.2 注意精確... 21

4.4 表示一個範圍,與sed(2,5p)意思相近... 21

4.5 BEGIN在讀取文件以前執行... 21

4.6 a=1輸出1a=lidaoawk會將lidao(英文字母)認爲是一個變量(需要加“”)... 21

4.7 END模式... 22

4.8 awk調試過程... 22

4.9 數組... 23

第5章企業案例... 23

5.1 企業面試題: 按單詞出現頻率降序排序(計算文件中每個單詞的重複數量)... 23

5.1.1 按字母查找... 24

5.2 考試題1:處理以下文件內容,將域名取出並根據域名進行計數排序處理:(百度和sohu面試題)24

5.2.1 答案:... 24

5.3 【】企業面試題】處理以下文件內容,將域名取出並根據域名進行計數排序處理:(百度和sohu面試題)24

5.3.1 答案:... 25

5.3.2 方法一... 26

5.3.3 方法二... 26

awk課程總結

第1章 awk基礎入門

要弄懂awk程序,必須熟悉瞭解這個工具的規則,

1.2 awk簡介

1.2.1 一種名字怪異的語言

1.2.2 模式掃描和處理

awk不僅僅是Linux中的一個命令,而且是一種編程語言,可以用來處理數據和生成報告,處理的數據可以是一個或者多個文件,可以是來自標準輸入,也可以是通過管道獲取標準輸入,awk可以在命令行上直接編輯命令進行操作,也可以編寫成awk程序來進行運用,本章主要講解awk命令行的運用,較爲複雜的程序會包含在以後的課程中

  回顧sed命令,把文件當做流水一樣處理

1.3 學過awk可以掌握的內容

 1記錄和字段

 2 模式匹配:模式與動作

 3 基本的awk執行過程

 4awk常用的內置變量(預定義變量)

 5 awk數組(工作常用的)

 6awk語法:循環,條件

 7awk常用的函數

 8 向awk傳遞參數

 9awk引用shell變量

10 awk小程序及調試思路

1.4 awk命令

awk -v RS=":"  與‘BEGIN{RS=":"}’一樣

uniq 合併相同行    -c  將相同行相加輸出

sort  排序, 默認按照字母順序排序   -r 逆向排序     -n  排序

culomn -t      使行,列對齊

awk的默認的FS 分隔符 空格序列  TAB鍵 一個或者多個空格 ,都認爲是一個整體

OFS不支持正則表達式

FS=-F  指定分隔符

posix   使awk支持擴展正則表達式,如:'/0{2,3}/'

awk中  $N==root    要寫成$N=="root"   如果不佳雙引號,awk會把等於看成是一個變量

例子:

[root@oldboy32-vm1~]# awk -F ":"'NR<=5{print $1,$3}' /etc/passwd

root 0

bin 1#awk 參數 '條件(找誰){動作(幹啥)}' /etc/passwd

1.5 模式及pattern,可以類似理解成sed的模式匹配,可以由表達式組成,也可以是倆個正斜槓之間的正則表達式,比如:NR==1,這就是模式,可以理解爲一個條件。

1.6 動作即action,是由在大括號裏面的一條或者多條語句組成,語句之間使用分號隔開,如下awk使用格式

awk處理的內容可以來自標準輸入(>),一個或者多個文本或管道

模式動作裏面分倆部分,大括號外面的叫找誰裏面的叫幹啥

1.7 awk執行過程

1 首先讀取一行

2 模式是我要處理的行嗎?

3 如果是,則對讀入行執行動作裏的命令

4 如果否,則重複上面的過程直到最後一個文件結尾

5 END模塊

6 結束

1.8 接下來說倆個新概念:記錄和字段,這裏爲了方便理解可以把記錄當做行記錄===行,字段相當於列,字段===列。

record

記錄 ,行

field

域,區域,字段,列

1.9 awk記錄分隔符 -RS

記錄分隔符 -每一個記錄是如何結束的

[root@zxw files]# cat reg.txt

Zhang (FS)Dandan41117397:250:100:175$0

RS

Zhang (FS)Xiaoyu390320151:155:90:201$0

RS

Meng(FS)Feixue80042789:250:60:50$0

RS

1.9.1 awk默認情況下每一行都是一個記錄

1.9.2 RS即record separator輸入數據記錄分隔符,每一行是怎麼來的,表示每個記錄輸入的時候的分隔符,即行與行之間如何分割。

例子:

awk指定RS分割符號:

[root@oldboy32-vm1files]# head -2 awkfile.txt

root:x:0:0:root:/root:/bin/bash

bin:x:1:1:bin:/bin:/sbin/nologin

[root@oldboy32-vm1files]# awk 'BEGIN{RS="/"}{print NR,$0}' awkfile.txt

1root:x:0:0:root:

2 root:

3 bin

4 bash

1.9.3 NR即number of record 記錄行號,表示當前正在處理的行的號碼

取oldboy

[root@oldboy32-vm1files]# echo "I am oldboy,my qq is31333741">>/server/files/oldboy.txt

[root@oldboy32-vm1files]# cat oldboy.txt

I am oldboy,myqq is 31333741

[root@oldboy32-vm1files]# echo oldboy,31333741

oldboy,31333741

[root@oldboy32-vm1files]# awk -F " |," '{print $3,$NF}'oldboy.txt

oldboy31333741

[root@oldboy32-vm1files]# awk -F " |," '{print$3","$NF}' oldboy.txt

oldboy,31333741

[root@oldboy32-vm1files]# awk -F "[ ,]" '{print$3","$NF}' oldboy.txt

oldboy,31333741

1.9.4 ORS即output record separator 輸出記錄分隔符。

1.9.5 awk使用內置變量RS來存放輸入記錄分隔符,RS表示的是輸入的記錄分隔符,這個值可以通過BEGIN模塊重新定義修改。

1.10 思路

1 讓所有的單詞排成一列,這樣每個單詞都是單獨的一行

2 設置RS的值爲空格

3 將文件裏面的所有空格替換爲回車換行符“\n”

4 grep所有連續的字母,grep -o 參數讓他們排成一排

整體思路 :想辦法讓所有單詞排成一行,站成一隊,排序,合併重複的,顯示重複數量

1.11 awk記錄知識小結

1.11.1 NR存放着每個記錄的號(行號),讀取新行時候會自動加1(+1)

1.11.2 RS是輸入數據的記錄的分隔符,簡單理解就是可以指定每個記錄的結尾標緻

1.11.3 RS作用就是表示一個記錄的結束

1.11.4 當我們修改了RS的值,最好配合NR來查看變化,也就是修改了RS的值通過NR查看結果,調試awk程序。

1.11.5 ORS輸出數據的記錄的分隔符

ORS

[root@oldboy32-vm1files]# cat ors.txt

a

b

c

[root@oldboy32-vm1files]# awk 'BEGIN{ORS="oldboy"}{print $0}'ors.txt

aoldboyboldboycoldboy[root@oldboy32-vm1files]#

1.12 awk學習技巧一則

大象放冰箱分幾步?  打開冰箱門,把大象放進去,關上冰箱門。awk也是一樣,一步一步來,先修改RS,然後用NR調試,看看到底如何分割的,然後通過sort排序,uniq去掉重複的。

1.13 字段(字段)

每條記錄都是由多個區域組成的,默認情況下區域之間的分隔符是由空格(即空格或者製表符)來分割,並且將分隔符記錄在內置變量FS中每行記錄的區域數據保存在awk的內置變量NF中

約定:

      field有很多多種解釋,域,記錄,區域,爲了方便理解統一使用區域表示field。

Zhang (FS)Dandan41117397:250:100:175$0

RS

Zhang (FS)Xiaoyu390320151:155:90:201$0

RS

Meng (FS) Feixue80042789:250:60:50$0

RS

Wu(FS)Waiwai70271111:250:80:75$0

RS

Liu(FS)Bingbing41117483:250:100:175   $0

RS

Wang(FS)Xiaoai3515064655:50:95:135  $0

RS

Zi(FS)Gege1986787350:250:168:200   $0

1.14 FS

FS即field separator,輸入字段(列)分隔符,分隔符就是菜刀,把一行字符串切爲很多個區域。

NF即number offields ,表示一行中列的個數,可以理解爲菜刀切過一行後,切成了多少份,OFS輸出字段(列)分隔符

awk使用內置變量FS來記錄區域分隔符的內容,FS可以在命令行上通過 F 參數來更改,也藝客通過BEGIN模塊來更改。

然後通過$n ,n是整數,來取北切割後的區域,$1取第一個區域,$2取第二個區域,$NF取最後一個區域。

列子

[root@oldboy32-vm1files]# ifconfig eth0 |awk 'NR==2{print $1}'

inet

[root@oldboy32-vm1files]# ifconfig eth0 |awk -F "[ :]+"'NR==2{print $1}'

[root@oldboy32-vm1files]# ifconfig eth0 |awk -F "[ :]+"'NR==2{print $2}'

inet

[root@oldboy32-vm1files]# #awk默認的FS 分隔符空格序列一個空格或多個空格 tab 都認爲是一樣的一個整體

[root@oldboy32-vm1files]# #[ \t]+

[root@oldboy32-vm1files]# echo -e "\ta\t\tb"

ab

[root@oldboy32-vm1files]# echo -e "\ta\t\tb"|awk '{print $1}'

a

[root@oldboy32-vm1files]# echo -e "\ta\t\tb"|awk '{print $2}'

b

1.15 說明:

這個文件的開頭有很多連續的空格,然後纔是inet這個字符

當我們使用默認的分隔符的時候,$1是有內容的

當我們指定其他分隔符(費空格),是的時候區域會有所變化

到底爲何會這樣,我們在這裏不在深究,只要瞭解有這種情況,注意一下就行,因爲這個樣的結果會僅僅會導致,其餘串成一個。

1.16 ORS與OFS簡介

OFS與ORS是awk的倆個內置變量

RS是輸入記錄分隔符,決定awk如何讀取或分隔符每行(記錄)

ORS表示輸出記錄分隔符,決定awk如何輸出一行(記錄)的,默認是回車換行符—(/n)

OFS表示輸出區域分隔符,決定awk輸出每個區域的時候用什麼分隔符

FS表示輸入區域分隔符,決定awk輸出每個區域的時候用什麼分隔符

awk無比強大,可以通過RS,FS,決定awk如何讀取數據,也可以通過修改ORS,OFS的值來指定awk如何輸出結果。

1.16.1 利用OFS調換ETCpasswd位置

[root@oldboy32-vm1files]# awk'BEGIN{FS=":"}{print $NF,$2,$3,$4,$5,$6,$1}' awkfile.txt

/bin/bashx 0 0 root /root root

/sbin/nologinx 1 1 bin /bin bin

/sbin/nologinx 2 2 daemon /sbin daemon

[root@oldboy32-vm1files]# awk'BEGIN{FS=":";OFS=":"}{print $NF,$2,$3,$4,$5,$6,$1}'awkfile.txt

/bin/bash:x:0:0:root:/root:root

/sbin/nologin:x:1:1:bin:/bin:bin

/sbin/nologin:x:2:2:daemon:/sbin:daemon

1.17 awk都有哪幾種模式

1.17.1 正則表達式作爲模式

1.17.2 比較表達式作爲模式

1.17.3 範圍模式

1.17.4 特殊模式BEGIN和END

awk的模式是你學好awk的必備也是最基礎的內容,必須熟練掌握

1.18 awk也支持大量的正則表達式,大部分與sed的元字符類似,而且正則表達式是玩轉三劍客的必備工具,

以什麼開頭,精確到列

[root@oldboy32-vm1files]# awk '$3~/c/' count.txt

sync xsync sbin bin sync

uucp xuucp var spool uucp sbin nologin

[root@oldboy32-vm1files]# awk '$3~/c$/' count.txt

sync xsync sbin bin sync

[root@oldboy32-vm1files]# awk '/c$/' count.txt

sync xsync sbin bin sync

[root@oldboy32-vm1files]# awk '$0~/c$/' count.txt

sync xsync sbin bin sync

下面的元字符是AWK的正則表達式符號,基本與sed相同,除了 ( ^ $ ) 他倆有點不i同

元字符

功能

示例

解釋

^

字符串開頭

/^oldboy/

$3~/^oldboy/

匹配所有以oldboy開頭的字符串

匹配出所有第三列中以oldboy開頭

$

字符串結尾

/oldbou$/

匹配所有以oldbou結尾的文本(字符串)

匹配第三列中以oldboy結尾的文本

.

匹配任意單個字符(包括回車符)

/o....y/

匹配字母o,然後兩個任意字符,再以y結尾的行。如:oldboy,oldddy

*

重複0個或多個前一個字符

/a*cool/

匹配0個或多個a之後緊跟着cool的行,比如:cool,aacool

+

重複前一個字符一次或多次

/a+b/

匹配一個或多個a緊跟着加b的行,如:ab,aaab,aaaaab

重複前一個字符0到1次

/a?b/

匹配0個或1個a,緊跟着b,如:b,ab

[ ]

匹配指定字符組內的任一個字符

/^[abc]/

匹配以字母a或b或c開頭的行

[^]

匹配不再指定字符組內的任一個字符

/^[^abc]/

匹配不以字母a或b或c開頭的行

( )

子表達式組合

/(cool)+/

表示一個或多個cool組合,當一些字符需要組合一個整體時,使用括號括起來

|

或者的意思

/(cool)|B/

匹配cool或者字母B的行

1.19 說明:

-F 指定分隔符,現在應該知道-F 和FS也是支持正則表達式的了把

[ :]+表示連續的空格或者冒號

-F "[ :]"以連續的空格或者冒號爲分隔符

/zhang/表示條件,整行中包Zhang字符的這個條件

{print$1,$(NF-1)} 表示動作,滿足條件後,執行顯示第一列($1)和倒數第二列($(NF-1) 當然$5也可以。

注意:

NF是一行中有多少列,NF-1 整行就是倒數第二列

$(NF-1)就是取倒數第二列內容

1.20 awk注意事項說明:

awk在輸出整行即$0的時候,僅僅是原封不動的輸出整行,沒有任何修改,這就造成一個問題,如果我修改了OFS,那麼輸出整行的時候print $0的時候,也不會有任何改變,即:如果awk的action動作沒有改行的內容,OFS都不會生效。

所以我們需要讓awk知道$0被修改了,這一個事情

$1=$1 是把$1的值賦值給了$1這顯然不會修改任何內容,但是這個動作會通知awk我修改了$1的內容,所以再次修改print $0的時候,$0的內容就變化了。

這是一個小技巧、

1.21 awk運算符

awk是一種編程語言,能夠進行更爲複雜的判斷,,當條件爲真的時候,awk就會執行相關的action,主要是在針對某一區域做出相關的判斷,比如打印成績在80分以上的行,這樣就必須對一個區域做比較判斷, awk可以使用的關係運算符,可以用來比較數字者字符串,哈un有正則表達式,當表達式爲真的時候,表達式結果爲1,否之爲0 ,只有表達式爲真,awk才執行相關action。

運算符

含義

示例

小於

x>y

<=

小於或等於

x<=y

==

等於

x==y

!=

不等於

x!=y

>.

大於

x>y

>=

大於或等於

x>=y

以上的運算符均是針對數字,下面倆個運算符正對字符串

~

與正則表達式匹配

x~/y/

!~

與正則表達式不匹配

x!~y

第2章 awk特殊模式與END模式

2.1 BEGIN模塊

BEGIN模塊在awk讀取文件之前就執行,一般用來定義我們的內置變量(預定義變量,eg.FSRS)

可以輸出表頭,(類似excel)表格名稱)

BEGIN模式之前我們有在示例中提到,自定義變量,給內容變量賦值等,都使用過,需要注意的是DEGIN模式後面需要接一個action操作塊,包含大括號內,awk必須在對輸入文件進行任何處理錢都需要先執行BEGIN裏的動作,我們可以不要任何輸入文件,就可以對BEGIN模塊進行測試,因爲awk需要先執行BEGIN模式,才能對輸入文件做處理,BEGIN模式常用來修改內置變量,ORS,RS,FS,OFS,等的值。

2.2 命令行 -F本質就是修改的FS變量

2.2.1 第二個作用,在讀取文件之前輸出些提示性信息,表頭。

顯示文件awkfile.txt的第一列和第三列(passwd前10行)並在第一行useraanme和UID

[root@zxw files]# awk -F: 'BEGIN{print"useradd","UID"}{print $1 ,$3}'awkfile.txt

useradd UID

root 0

bin 1

daemon 2

adm 3

2.3 awk中的變量的概念簡介

直接定義,直接使用即可

awk中字母將會被認爲是變量,如果真的要給一個變量賦值字母,(字符串),請使用雙引號。

[root@zxwfiles]# awk'BEGIN{abcd=123456;a=abcd;print a}'

123456

[root@zxwfiles]# awk'BEGIN{a=abcd;print a}'

[root@zxwfiles]# awk'BEGIN{a="abcd";print a}'

abcd

2.4 NEGIN模式說明

沒有文件awk依舊可以處理BEGIN模式下的動作(命令)

2.5 END模塊說明

END在awk讀取完文件的時候,再執行END模塊,一般用來輸出一個結果。(累加,數組結果),也可以是和BEGIN模塊類似的結尾標示信息。

與BEGIN模式相對應的END模塊,格式一樣,但是END模塊僅在awk處理萬所有行後才進行處理。

2.6 awk編程思想

2.6.1 先處理,最後在END模式輸出

2.6.2 {print NF ,$0} boby 模塊處理,處理完畢後

.6.3 END{print"endof file"} 輸出一個結果

2.7 awk調試技巧:

讓awk顯示出每一步的執行結果。

一般通過print來配合完成

2.8 幾種常用的運算表達式

c=c+1   >c++

c=c+2   >c+=2

c=c+$0  >c+=$0

2.9 awk中的動作

在一個模式-動作語句中,模式決定動作什麼時候執行,有時候動作會非常簡單:一條單獨的打印

或賦值語句,在有些時候,動作有可能是多條語句,語句之間用換行符或者都好分開。

awk的動作中如果有倆個或者倆個以上的語句,需要用分號分開

動作部分理解爲花括號裏面的內容即可,總體分爲:

1       表達式

2       流程控制語句

3       空語句

4       數組

2.10 awk模式與動作小結

awk命令核心由模式和動作倆部分組成,就是找誰{幹啥}

模式就是條件,動作就是具體幹什麼

1正則表達式

2條件表達式

3範圍表達式

注意BEGIN或者END模塊只能有一個,BEGIN{}BEGIN{} 或者END{}END{}都是錯誤的。

找誰幹嗎模塊可以是多個

BEGIN AWK中只能有一個

END awk中只能有一個

他倆可以同時出現

2.11 awk執行過程文字版

1  命令行的賦值(-F或-)

2  執行BEGIN模式裏面的內容

3       開始讀取文件

4  判斷條件(模式)是否成立

成立則執行對應動作裏面的內容

讀取下一行,循環判斷

直到讀取到最後一個文件的結尾

5  最後執行END模式裏面的內容

5       結束

第3章 awk數組

awk提供了數組來存放一組相關的值

awk是一種編程語言,肯定也支持數組的運用,但是有不同與C語言的數組,數組在awk中被稱爲關聯數據,因爲它的下標既可以是數字也可以是字符串,下標通常北稱爲key,並且與對應的數組元素的值關聯,數組元素的key和值都存放在awk程序內部的一張表中,通過一定散列算法來儲存,所以數組元素都不是按照順序相互尋的,打印出來的也肯定不是按序號一定的順序,但是我們可以通過管道來實現對所需要的數據再次操作來表達自己的效果。

3.1 圖片-數組-酒店

老男孩教育酒店

oldboyhotel

酒店裏面的幾個房間

110oldboyhotel[110]

119oldboyhotel[119]

121oldboyhotel[121]

114oldboyhotel[114]

酒店裏面住的客人

101房間住着xiaoyu oldboyhotel[110] ="xiaoyu"

119房間住着ruxueoldboyhotel[119]="ruxue"

120房間住着dandanoldboyhotel[121="dandan"

114房間住着waiwaioldboyhotel[114]="waiwai"

3.2 awk數組小結

pol

in

hotel

變量

關鍵字

數組名

警察

找人

酒店名稱

for循環

for (pol in hotel)

循環(循環 找人  酒店名稱)

pol===房間號碼===數組元素名字===數組的下標([ ])===門把手

hotel[pol]===GPS定位 ===酒店名稱 [房間號碼]

hotel [ "b" ]===print  hotel["b"]

3.4 企業面試題數組題分解執行過程

指定分隔符

單引號

創建awk數組(酒店)

取結果

單引號


awk -F "[/.]+"

'

{hotel[$2]++}

c++

END{for (pol in hotel)}

print pol , hotel [pol]

'

sort.txt

思路:先處理後輸出(END模塊輸出)

第4章 練習題

4.1 測試文件

[root@zxwfiles]# cat reg.txt

ZhangDandan41117397:250:100:175

ZhangXiaoyu390320151:155:90:201

4.1.1 顯示姓Zhang的人的第二次捐款金額及她的名字

4.1.1.1 第一種

[root@zxw files]# awk -F "[:]+" '/Zhang/{print $1,$2,$6}' reg.txt

Zhang Dandan 175

Zhang Xiaoyu 201

4.1.1.2 第二種

[root@oldboy32-vm1files]# awk -F "[ :]+" '/^Zhang/' reg.txt

ZhangDandan41117397:250:100:175

ZhangXiaoyu390320151:155:90:201

4.1.1.3 第三種

[root@oldboy32-vm1files]# awk -F "[ :]+" '$0~/^Zhang/' reg.txt

ZhangDandan41117397:250:100:175

ZhangXiaoyu390320151:155:90:201

4.1.1.4 第四種

[root@oldboy32-vm1files]# awk -F "[ :]+" '/^Zhang/{print$2,$5}' reg.txt

Dandan100

Xiaoyu90

4.1.1.5 注意錯誤1

[root@oldboy32-vm1files]# awk -F "[ :]+" '/^Zhang/{print$2,$NF-1}' reg.txt

Dandan174

Xiaoyu200

4.1.1.6 注意錯誤2

[root@oldboy32-vm1files]# awk -F "[ :]+" '/^Zhang/{print$2,$(NF-1)}' reg.txt

Dandan100

Xiaoyu90

4.1.2 顯示Xiaoyu的名字和ID號碼

[root@zxwfiles]# awk -F "[ :]+" '/Xiaoyu/{print$1,$2,$3}' reg.txt

ZhangXiaoyu 390320151

4.1.3 顯示所有以41開頭的ID號碼的人的全名和ID號碼

[root@zxwfiles]# awk -F "[ :]+" '$3~/^41/ {print $1 $2$3}' reg.txt

ZhangDandan41117397

LiuBingbing41117483

4.1.4 顯示所有以一個D或X開頭的人名全名

[root@zxwfiles]# awk -F "[ :]+" '$2~/^D|^X/{print$1,$2}' reg.txt

ZhangDandan

ZhangXiaoyu

WangXiaoai

4.1.5   顯示所有ID號碼最後一位數字是1或5的人的全名

[root@zxwfiles]# awk -F "[ :]+" '$3~/1$|5$/{print$1,$2}' reg.txt

ZhangXiaoyu

WuWaiwai

WangXiaoai

4.1.6   顯示Xiaoyu的捐款.每個值時都有以$開頭.如$520$200$135

4.1.6.1 第一種

[root@zxwfiles]# awk'BEGIN {FS=":" ; OFS="$"} {print "$",$2,$3,$4}' reg.txt

250$100$175

155$90$201

250$60$50

4.1.6.2 第二種

[root@oldboy32-vm1files]# awk '$2~/^Xiaoyu$/{print $NF}' reg.txt

:155:90:201

[root@oldboy32-vm1files]# awk '$2~/^Xiaoyu$/{print $NF}' reg.txt |tr":" "$"

$155$90$201

[root@oldboy32-vm1files]# #sub gsub gensub

[root@oldboy32-vm1files]# #gsub

[root@oldboy32-vm1files]# #gsub(r, s [, t])

[root@oldboy32-vm1files]# #函數

[root@oldboy32-vm1files]# #gsub(正則表達式,你要替換成啥[,目標($1 $2 $3)])

[root@oldboy32-vm1files]# awk '$2~/^Xiaoyu$/{gsub(/:/,"$")}'reg.txt

[root@oldboy32-vm1files]# awk'$2~/^Xiaoyu$/{gsub(/:/,"$");print $NF}' reg.txt

$155$90$201

[root@oldboy32-vm1files]# awk'$2~/^Xiaoyu$/{gsub(/:/,"$",$NF);print $NF}' reg.txt

$155$90$201

4.1.6.3 第三種

awk'BEGIN {FS=":";OFS="$"}{print "",$2,$3,$4}' reg.txt

4.1.6.4 疑問(下面$0和$1,$2,$3)輸出的結果爲啥不一樣

[root@oldboy32-vm1 files]#awk -F : -v OFS="$"'{print $0}' reg.txt

ZhangDandan41117397:250:100:175

ZhangXiaoyu390320151:155:90:201

MengFeixue80042789:250:60:50

[root@oldboy32-vm1files]# awk -F : -v OFS="$"'{print $1,$2,$3}' reg.txt

ZhangDandan41117397$250$100

ZhangXiaoyu390320151$155$90

LaoNanhai918391635$250$100

XManX10000$999$999

[root@oldboy32-vm1files]# awk -F : -v OFS="$"'{print $1,$2,$3,$4}' reg.txt

ZhangDandan41117397$250$100$175

ZhangXiaoyu390320151$155$90$201

MengFeixue80042789$250$60$50

[root@oldboy32-vm1files]# awk -F : -v OFS="$"'{$1=$1;print $0}' reg.txt

ZhangDandan41117397$250$100$175

ZhangXiaoyu390320151$155$90$201

LiYoujiu918391635$175$75$300

4.1.6.5 顯示所有人的全名,以姓,名的格式顯示,如Meng,Feixue

[root@zxwfiles]# awk'BEGIN {FS="[ ]+";OFS=","}{print $2,$1}' reg.txt

Dandan,Zhang

Xiaoyu,Zhang

Feixue,Meng

4.2 正則表達式部分的疑問

[root@demon files]# awk '/^Xiaoyu/' /server/files/reg.txt

[root@demon files]# awk '$2~/^Xiaoyu/' /server/files/reg.txt

/^Xiaoyu/的意思不是以Xiaoyu爲開頭的字符串嗎,爲什麼默認$0匹配就不行了?

/Xiaoyu/這樣就可以了,這是爲什麼?

解答:

awk不會自動匹配,需要明確告訴它是那一列

^          matches the beginning of astring.  #匹配字符串的開頭的位置

$          matches the end of a string.        #匹配字符串結尾的位置

awk '/^Xiaoyu/' /server/files/reg.txt

awk '/Xiaoyu/' /server/files/reg.txt

grep "^Xiaoyu" reg.txt

grep "Xiaoyu" reg.txt

4.3 匹配除了含有oldboy的其他行

4.3.1 測試文件

[root@zxw files]# cat test.txt

lidao

oldboy

oldboylinux

zhangdao

xiadao

[root@zxw files]#

4.3.2 注意精確

[root@oldboy32-vm1files]# awk '/^l|z|x|x$/' test.txt

lidao

oldboylinux

zhangdao

[root@oldboy32-vm1files]# egrep "^l|z|x|x$" test.txt

lidao

oldboylinux

zhangdao

[root@oldboy32-vm1files]# egrep "^l|x$|^z|^x" test.txt

lidao

oldboylinux

zhangdao

4.4 表示一個範圍,與sed(2,5p)意思相近

[root@oldboy32-vm1files]# awk 'NR==2,NR==5' awkfile.txt

bin:x:1:1:bin:/bin:/sbin/nologin

daemon:x:2:2:daemon:/sbin:/sbin/nologin

adm:x:3:4:adm:/var/adm:/sbin/nologin

lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

[root@oldboy32-vm1files]# #範圍條件/範圍模式

4.5 BEGIN在讀取文件以前執行

[root@oldboy32-vm1files]# awk 'BEGIN{print 3/10}'

0.3

[root@oldboy32-vm1files]# awk 'BEGIN{print 10/3}'

3.33333

4.6 a=1  輸出1 a=lidao  awk會將lidao(英文字母)認爲是一個變量(需要加“”)

[root@oldboy32-vm1files]# awk 'BEGIN{a=1;print a}'

1

[root@oldboy32-vm1files]# awk 'BEGIN{a=lidao;print a}'

[root@oldboy32-vm1files]# awk 'BEGIN{a="";print a}'

[root@oldboy32-vm1files]# awk 'BEGIN{a="lidao";print a}'

lidao

4.7 END模式

[root@oldboy32-vm1 files]# awk'BEGIN{print "name","ID"}{print $2,$3}END{print"hello" }' reg.txt

name ID

Dandan 41117397

Xiaoyu 390320151

Feixue 80042789

hello

4.8 awk調試過程

[root@oldboy32-vm1~]# awk '/^$/{notepad++}END{print notepad}'/etc/services16

[root@oldboy32-vm1~]# awk '/^$/{notepad++;print notepad}'/etc/services

1

2

3

4.9 數組

[root@oldboy32-vm1~]# awk'BEGIN{hotel[110]="xiaoyu";hotel[114]="xiadao";

hotel[121]="dandan"

hotel[119]="waiwai"

print hotel[110],hotel[114],hotel[119],hotel[121]}'

xiaoyuxiadao waiwai dandan

[root@oldboy32-vm1~]# awk'BEGIN{hotel[110]="xiaoyu";hotel[114]="xiadao";

hotel[121]="dandan"

hotel[119]="waiwai"

for(pol in hotel )print pol,hotel[pol]}'

110xiaoyu

121dandan

114xiadao

119waiwai

數組

[root@zxw~]# awk 'BEGIN{hotel[100]="zxw";hotel[200]="mzl";hotel[300]="wyf";hotel[400]="yz";for(abc in hotel)print abc,hotel[abc]}'

100 zxw

200 mzl

300 wyf

400 yz

第5章 企業案例

5.1 企業面試題: 按單詞出現頻率降序排序(計算文件中每個單詞的重複數量)

注:(此處使用sort與uniq即可)

[root@oldboy32-vm1files]# #sort 默認是按照字母順序排列

awk -vRS=" " '{print $0}' count.txt|xargs -n1|sort|uniq -c|sort -nr

awk -vRS=" " '{print $0}' count.txt|sort|uniq -c|sort -nr

5.1.1 按字母查找

awk 'BEGIN{RS="[:0-9/ ]+"}{printNR,$0}' awkfile.txt

awk 'BEGIN{RS="[^a-zA-Z]+"}{printNR,$0}' awkfile.txt

[root@zxwfiles]# awk 'BEGIN{RS=":|/|[0-9]"}{print $0}' awkfile.txt|sort|uniq-c|sort -rn

5.2 考試題1:處理以下文件內容,將域名取出並根據域名進行計數排序處理:(百度和sohu面試題)

oldboy.log

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

5.2.1 答案:

[root@zxwfiles]# awk 'BEGIN{FS="."}{print$3}' oldboy.txt|sort|uniq -c |sort -rn

3 org/index

1 org/3

1 org/2

1 org/1

[root@zxwfiles]#

5.3 【企業面試題】處理以下文件內容,將域名取出並根據域名進行計數排序處理:(百度和sohu面試題)

[root@zxwfiles]# cat oldboy.txt

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

[root@zxwfiles]#

5.3.1 答案:

[root@oldboy32-vm1files]# awk -F "[/.]+" '{h[$2]++;print$2,h["www"]}' url.txt

www 1

www 2

post 2

mp3 2

www 3

post 3

[root@oldboy32-vm1files]# awk -F "[/.]+" '{h[$2]++;print$2,h["www"]}' url.txt

[root@oldboy32-vm1files]# awk -F "[/.]+" '{h[$2]++;print$2,h[""]}' url.txt

[root@oldboy32-vm1files]# awk -F "[/.]+" '{h[$2]++;print$2,h["post"]}' url.txt

[root@oldboy32-vm1files]# awk -F "[/.]+" '{h[$2]++;print$2,h[$2]}' url.txt

[root@oldboy32-vm1files]# awk -F "[/.]+" '{h[$2]++}END{for(polin h) print pol,h[pol]}' url.txt

www 3

mp3 1

post 2

[root@oldboy32-vm1files]# awk -F "[/]+" '{h[$2]++}END{for(polin h) print pol,h[pol]}' url.txt

mp3.etiantian.org1

post.etiantian.org2

www.etiantian.org3

5.3.2 方法一

awk -v RS="[^a-zA-Z]+"'{h[$0]++}END{for(pol in h)print pol,h[pol]}' awkfile.txt |sort-rnk2|column -t

5.3.3 方法二

awk'BEGIN{RS="[^a-zA-Z]+"}{h[$0]++}END{for(pol in h)printpol,h[pol]}' awkfile.txt |sort -rnk2|column -t

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章