目錄
1.5模式及pattern,可以類似理解成sed的模式匹配,可以由表達式組成,也可以是倆個正斜槓之間的正則表達式,比如:NR==1 ,這就是模式,可以理解爲一個條件。... 2
1.6動作即action,是由在大括號裏面的一條或者多條語句組成,語句之間使用分號隔開,如下awk使用格式... 2
1.8 接下來說倆個新概念:記錄和字段,這裏爲了方便理解可以把記錄當做行記錄===行,字段相當於列,字段===列。... 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.11.1 NR存放着每個記錄的號(行號),讀取新行時候會自動加1(+1)... 6
1.11.2 RS是輸入數據的記錄的分隔符,簡單理解就是可以指定每個記錄的結尾標緻... 6
1.11.4 當我們修改了RS的值,最好配合NR來查看變化,也就是修改了RS的值通過NR查看結果,調試awk程序。... 6
1.16.1 利用OFS調換ETCpasswd位置... 8
1.18 awk也支持大量的正則表達式,大部分與sed的元字符類似,而且正則表達式是玩轉三劍客的必備工具,... 9
2.2.1 第二個作用,在讀取文件之前輸出些提示性信息,表頭。... 11
2.6.2 {print NF ,$0} boby 模塊處理,處理完畢後... 12
2.6.3 END{print"end of file"} 輸出一個結果... 12
4.1.1 顯示姓Zhang的人的第二次捐款金額及她的名字... 16
4.1.3 顯示所有以41開頭的ID號碼的人的全名和ID號碼... 17
4.1.5 顯示所有ID號碼最後一位數字是1或5的人的全名... 17
4.1.6 顯示Xiaoyu的捐款.每個值時都有以$開頭.如$520$200$135. 18
4.4 表示一個範圍,與sed(2,5p)意思相近... 21
4.6 a=1輸出1a=lidaoawk會將lidao(英文字母)認爲是一個變量(需要加“”)... 21
5.1 企業面試題: 按單詞出現頻率降序排序(計算文件中每個單詞的重複數量)... 23
5.2 考試題1:處理以下文件內容,將域名取出並根據域名進行計數排序處理:(百度和sohu面試題)24
5.3 【】企業面試題】處理以下文件內容,將域名取出並根據域名進行計數排序處理:(百度和sohu面試題)24
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