【現(xiàn)學現(xiàn)忘&Shell編程】— 33.AWK編程之a(chǎn)wk的條件

1、awk的條件

2、說明

以下練習使用如下文本

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í)行時機是在awk程序一開始時,尚未讀取任何數(shù)據(jù)之前執(zhí)行。

BEGIN后的動作只執(zhí)行一次,因為當awk開始從文件中讀入數(shù)據(jù),BEGIN的條件就不再成立,所以BEGIN定義的動作只能被執(zhí)行一次。

練習:執(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命令只要檢測不到完整的單引號不會執(zhí)行,所以這個命令的換行不用加入\,就是一行命令

  • 上邊命令定義了兩個動作

    第一個動作使用BEGIN條件,所以會在讀入文件數(shù)據(jù)前打印“This is BEGIN action”(只會執(zhí)行一次)。

    第二個動作會打印文件中的對應文本。

(2)END

END也是awk保留字,不過剛好和BEGIN相反。

END是在awk程序處理完所有數(shù)據(jù),即將結(jié)束時執(zhí)行。END后的動作只在程序結(jié)束時執(zhí)行一次。

練習:執(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)容,而且只會執(zhí)行一次。

(3)關(guān)系運算符

假設(shè)我想看看Java績大于等于80分的學員是誰,就可以這樣輸入命令:

grep -v "Name" student.txt | awk '$6>=80 {printf $2 "\n"}'

# 判斷第六字段(Java成績)大于等于80分的行,如果判斷式成立,則打印第2列(學員名)
[root@localhost tmp]# grep -v "Name" student.txt | awk '$6>=80 {printf $2 "\n"}'
Tangs
Sunwk

grep -v "Name" student.txt是把標題過濾掉。

(4)說明awk中條件表達式的執(zhí)行過程

要先說明一下,雖然awk是列提取命令,但是也要按行來讀入的。

在awk處理一個文本文件的時候:

  • 先判斷表達式中有沒有BEGIN。

    如果有,就先執(zhí)行BEGIN定義的操作,且執(zhí)行一次。

  • 如果沒有BEGIN或者BEGIN定義的動作執(zhí)行完成之后,會把文本中的第一行數(shù)據(jù)讀入awk中,

    把該行的整行數(shù)據(jù)賦予$0變量中,

    把該行數(shù)據(jù)的第一列賦值在$1變量中,第二列賦值在$2變量中,以此類推。

  • 例如awk '{printf $2 "\n"}' student.txt,意思是打印文本中的第二列姓名。

    我們先忽略掉條件,流程是:

    awk讀取第一行數(shù)據(jù)(上面一步),然后執(zhí)行動作輸出第二列信息,也就是輸出第一行的第二列信息。

    然后開始讀取第二行數(shù)據(jù),然后再執(zhí)行動作,輸出第二行的第二列信息,

    然后再讀取第三行數(shù)據(jù),之后執(zhí)行動作,輸出第三行的第二列信息,

    以此類推,基本上就是這樣的一個過程。

  • 然后在加上條件awk '$6>=80 {printf $2 "\n"}' student.txt

    判斷第六列Java的成績大于80分,才輸出。

    還是和上邊一樣,先是awk讀取第一行數(shù)據(jù)完成之后,就要處理動作了,

    但是在處理動作之前,先要判斷一下動作前面的條件是否成立,

    如果成立,則執(zhí)行后邊的動作。

    如果不成立,則不執(zhí)行跟在后邊的動作。

    然后在開始讀取第二行數(shù)據(jù),重復上邊的流程,以此類推。

    總結(jié)一下就是:加入了條件之后,只有條件成立動作才會執(zhí)行,如果條件不滿足,則動作則不運行。

  • 最后如果有END,則把END中定義的動作執(zhí)行一次。

以上就是awk的執(zhí)行流程。

(5)awk中使用正則表達式

如果要想讓awk識別字符串,必須使用//包含,//中識別的就是正則表達式規(guī)則匹配的字符串。

例如:

# 輸出打印Sunwk的成績
# awk會匹配有Sunwk符號的行,并輸出
[root@localhost tmp]# awk '/Sunwk/ {print}' student.txt 
2   Sunwk   99  98  97  96.66

注意:這里要注意在awk中,使用//包含的字符串,awk命令才會查找。也就是說字符串必須用//包含,awk命令才能正確識別。

(6)A~B練習

A~B是A包含B的意思。

練習:查看Sunwk用戶的Java成績。

# 匹配第二字段中包含有“Sun”字符,則打印第六字段數(shù)據(jù)
[root@localhost tmp]# awk '$2 ~ /Sun/ {printf $6 "\n" }' student.txt 
96.66

提示:(6)練習的方式,是在某一列中查找是否包含一個字符串。而上面(5)的寫法,是在一行數(shù)據(jù)當中匹配是否包含一個字符串,根據(jù)需求靈活使用。

注意:~兩邊有無空格都可以。

拓展練習:

當使用df命令查看分區(qū)使用情況時,如果我只想查看真正的系統(tǒng)分區(qū)的使用狀況,而不想查看光盤和臨時分區(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% 
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容