1导街、awk的條件
2耻蛇、說明
以下練習(xí)使用如下文本
ID Name Python Linux MySQL Java
1 Tangs 88 87 86 85.55
2 Sunwk 99 98 97 96,66
3 Zhubj 77 76 75 74.44
4 Shahs 66 65 64 63.33
(1)BEGIN
BEGIN是awk的保留字吭从,是一種特殊的條件類型朝蜘。
BEGIN的執(zhí)行時(shí)機(jī)是在awk程序一開始時(shí),尚未讀取任何數(shù)據(jù)之前執(zhí)行涩金。
BEGIN后的動(dòng)作只執(zhí)行一次谱醇,因?yàn)楫?dāng)awk開始從文件中讀入數(shù)據(jù),BEGIN的條件就不再成立步做,所以BEGIN定義的動(dòng)作只能被執(zhí)行一次副渴。
練習(xí):執(zhí)行命令查看BEGIN作用:
awk 'BEGIN{print "This is BEGIN action"} {printf $2 "\t" $3 "\t" $6 "\t" "\n"}' student.txt
[root@localhost tmp]# awk 'BEGIN{print "This is BEGIN action"} {printf $2 "\t" $3 "\t" $6 "\t" "\n"}' student.txt
This is BEGIN action
Name Python Java
Tangs 88 85.55
Sunwk 99 96.66
Zhubj 77 74.44
Shahs 66 63.33
說明:
awk命令只要檢測(cè)不到完整的單引號(hào)不會(huì)執(zhí)行,所以這個(gè)命令的換行不用加入
\
辆床,就是一行命令上邊命令定義了兩個(gè)動(dòng)作
第一個(gè)動(dòng)作使用BEGIN條件佳晶,所以會(huì)在讀入文件數(shù)據(jù)前打印“This is BEGIN action”(只會(huì)執(zhí)行一次)。
第二個(gè)動(dòng)作會(huì)打印文件中的對(duì)應(yīng)文本讼载。
(2)END
END也是awk保留字轿秧,不過剛好和BEGIN相反。
END是在awk程序處理完所有數(shù)據(jù)咨堤,即將結(jié)束時(shí)執(zhí)行菇篡。END后的動(dòng)作只在程序結(jié)束時(shí)執(zhí)行一次。
練習(xí):執(zhí)行命令查看END作用:
awk 'END{print "This is END action"} {printf $2 "\t" $3 "\t" $6 "\t" "\n"}' student.txt
[root@localhost tmp]# awk 'END{print "This is END action"} {printf $2 "\t" $3 "\t" $6 "\t" "\n"}' student.txt
Name Python Java
Tangs 88 85.55
Sunwk 99 96.66
Zhubj 77 74.44
Shahs 66 63.33
This is END action
說明:在輸出結(jié)尾輸入“This is END action”一喘,這并不是文檔本身的內(nèi)容驱还,而且只會(huì)執(zhí)行一次。
(3)關(guān)系運(yùn)算符
假設(shè)我想看看Java績(jī)大于等于80分的學(xué)員是誰(shuí)凸克,就可以這樣輸入命令:
grep -v "Name" student.txt | awk '$6>=80 {printf $2 "\n"}'
# 判斷第六字段(Java成績(jī))大于等于80分的行议蟆,如果判斷式成立,則打印第2列(學(xué)員名)
[root@localhost tmp]# grep -v "Name" student.txt | awk '$6>=80 {printf $2 "\n"}'
Tangs
Sunwk
grep -v "Name" student.txt
是把標(biāo)題過濾掉萎战。
(4)說明awk中條件表達(dá)式的執(zhí)行過程
要先說明一下咐容,雖然awk是列提取命令,但是也要按行來讀入的蚂维。
在awk處理一個(gè)文本文件的時(shí)候:
-
先判斷表達(dá)式中有沒有BEGIN戳粒。
如果有路狮,就先執(zhí)行BEGIN定義的操作,且執(zhí)行一次蔚约。
-
如果沒有BEGIN或者BEGIN定義的動(dòng)作執(zhí)行完成之后奄妨,會(huì)把文本中的第一行數(shù)據(jù)讀入awk中,
把該行的整行數(shù)據(jù)賦予
$0
變量中苹祟,把該行數(shù)據(jù)的第一列賦值在
$1
變量中砸抛,第二列賦值在$2
變量中,以此類推苔咪。 -
例如
awk '{printf $2 "\n"}' student.txt
锰悼,意思是打印文本中的第二列姓名。我們先忽略掉條件团赏,流程是:
awk讀取第一行數(shù)據(jù)(上面一步)箕般,然后執(zhí)行動(dòng)作輸出第二列信息,也就是輸出第一行的第二列信息舔清。
然后開始讀取第二行數(shù)據(jù)丝里,然后再執(zhí)行動(dòng)作,輸出第二行的第二列信息体谒,
然后再讀取第三行數(shù)據(jù)杯聚,之后執(zhí)行動(dòng)作,輸出第三行的第二列信息抒痒,
以此類推幌绍,基本上就是這樣的一個(gè)過程。
-
然后在加上條件
awk '$6>=80 {printf $2 "\n"}' student.txt
判斷第六列Java的成績(jī)大于80分故响,才輸出傀广。
還是和上邊一樣,先是awk讀取第一行數(shù)據(jù)完成之后彩届,就要處理動(dòng)作了伪冰,
但是在處理動(dòng)作之前,先要判斷一下動(dòng)作前面的條件是否成立樟蠕,
如果成立贮聂,則執(zhí)行后邊的動(dòng)作。
如果不成立寨辩,則不執(zhí)行跟在后邊的動(dòng)作吓懈。
然后在開始讀取第二行數(shù)據(jù),重復(fù)上邊的流程靡狞,以此類推耻警。
總結(jié)一下就是:加入了條件之后,只有條件成立動(dòng)作才會(huì)執(zhí)行,如果條件不滿足榕栏,則動(dòng)作則不運(yùn)行。
最后如果有END蕾各,則把END中定義的動(dòng)作執(zhí)行一次扒磁。
以上就是awk的執(zhí)行流程。
(5)awk中使用正則表達(dá)式
如果要想讓awk識(shí)別字符串式曲,必須使用//
包含妨托,//
中識(shí)別的就是正則表達(dá)式規(guī)則匹配的字符串。
例如:
# 輸出打印Sunwk的成績(jī)
# awk會(huì)匹配有Sunwk符號(hào)的行吝羞,并輸出
[root@localhost tmp]# awk '/Sunwk/ {print}' student.txt
2 Sunwk 99 98 97 96.66
注意:這里要注意在awk中兰伤,使用
//
包含的字符串,awk命令才會(huì)查找钧排。也就是說字符串必須用//
包含敦腔,awk命令才能正確識(shí)別。
(6)A~B
練習(xí)
A~B
是A包含B的意思恨溜。
練習(xí):查看Sunwk用戶的Java成績(jī)符衔。
# 匹配第二字段中包含有“Sun”字符,則打印第六字段數(shù)據(jù)
[root@localhost tmp]# awk '$2 ~ /Sun/ {printf $6 "\n" }' student.txt
96.66
提示:(6)練習(xí)的方式糟袁,是在某一列中查找是否包含一個(gè)字符串判族。而上面(5)的寫法,是在一行數(shù)據(jù)當(dāng)中匹配是否包含一個(gè)字符串项戴,根據(jù)需求靈活使用形帮。
注意:
~
兩邊有無(wú)空格都可以。
拓展練習(xí):
當(dāng)使用df
命令查看分區(qū)使用情況時(shí)周叮,如果我只想查看真正的系統(tǒng)分區(qū)的使用狀況辩撑,而不想查看光盤和臨時(shí)分區(qū)的使用狀況,則可以執(zhí)行如下:
# 查詢包含有sda+數(shù)字的行则吟,并打印第一字段和第五字段
[root@localhost tmp]# df -h | awk '/sda[0-9]/ {printf $1 "\t" $5 "\t" "\n"}'
/dev/sda3 12%
/dev/sda1 15%