1. 程式人生 > 實用技巧 >awk動作總結之二

awk動作總結之二

awk中的條件判斷語句。

比如 "if"

比如 "if...else..."

比如 "if...else if...else..."

我們說過,這些語句都可以歸類為"控制語句",但是這些並不是"控制語句"的全部,今天我們繼續聊聊awk的"控制語句"。

今天的話題主要與"迴圈"有關,說到"迴圈",你一定會想起 for、while 等字眼,沒錯,awk中也有for迴圈、while迴圈等控制語句。

其實,只要我們有一點點開發基礎,理解這些都不是什麼難事,因為它們的用法與其他程式語言中的用法並沒與什麼區別。

我們先來看一下這些迴圈控制語句的語法,然後再進行舉例。

#for迴圈語法格式1
for(初始化;布林表示式;更新){
//程式碼語句 } #for迴圈語法格式2 for(變數in陣列){ //程式碼語句 } #while迴圈語法 while(布林表示式){ //程式碼語句 } #do...while迴圈語法 do{ //程式碼語句 }while(條件)
[root@server01 ~]# awk 'BEGIN{for(i=1;i<=6;i++){print i}}'
1
2
3
4
5
6

上例中,我們使用了BEGIN模式,BEGIN模式對應的動作中,包含了for迴圈語句,看到這裡,是不是感覺與其他語言中的for迴圈完全沒有區別嘛?只不過,上例中的for迴圈語句都寫在了一行中而已。

再來看看while迴圈的具體使用,為了方便演示,仍然使用BEGIN模式,示例如下。

[root@server01 ~]# awk -v i=1 'BEGIN{while(i<6){print i;i++}}'
1
2
3
4
5
[root@server01 ~]# awk  'BEGIN{i=1;while(i<6){print i;i++}}'
1
2
3
4
5

當while對應的條件滿足時,則執行對應的語句,語句執行完成後,對條件進行修改。

同理,do...while的示例如下,它與while迴圈的不同之處在於,while迴圈只有當滿足條件時才會執行對應語句,而do...while迴圈則是無論是否滿足條件,都會先執行一遍do對應的程式碼,然後再判斷是否滿足while中對應的條件,滿足條件,則執行do對應的程式碼,如果不滿足條件,則不再執行do對應的程式碼。

[root@server01 ~]# awk 'BEGIN{i=1;do{print "test";i++}while(i<1)}'
test
[root@server01 ~]# awk 'BEGIN{i=1;do{print "test";i++}while(i<=5)}'
test
test
test
test
test

無論是否滿足while中的條件,都會先執行一遍do對應的程式碼。

那麼,說到迴圈,就不能不說說與迴圈有關的跳出語句。

沒錯,與其他程式語言中一樣,在awk中,同樣可以使用break與continue跳出迴圈。

continue的作用:跳出"當前"迴圈

break的作用:跳出"整個"迴圈

示例如下,先看看continue的示例

[root@server01 ~]# awk 'BEGIN{for(i=1;i<=6;i++){print i}}'
1
2
3
4
5
6
[root@server01 ~]# awk 'BEGIN{for(i=1;i<=6;i++){if(i==3){continue};print i}}'
1
2
4
5
6

由於在for迴圈中添加了條件判斷,所以當 i 的值為 3 時,跳過了"當前本次"迴圈,沒有執行當前本次迴圈需要執行的動作,所以上例中,數字"3"並沒有被打印出來。

當然,如果你想"結束"的更加"徹底",可以使用break結束迴圈,示例如下。

[root@server01 ~]# awk 'BEGIN{for(i=1;i<=6;i++){if(i==3){break};print i}}'
1
2

break結束的更加徹底,當使用break時,整個迴圈都將被結束,迴圈中的動作將不會再被執行。

continue與break同樣可以用於while迴圈與do...while迴圈,此處就不再贅述了。

當然,如果你經常編寫過shell指令碼,你可能會問,awk中有類似exit的語句嗎?必須有啊,在shell中,exit命令表示退出當前指令碼,在awk中,它的含義也是類似的,它表示不再執行awk命令,相當於退出了當前的awk命令,示例如下。

[root@server01 ~]# awk 'BEGIN{print 1;print 2;print 3}'
1
2
3
[root@server01 ~]# awk 'BEGIN{print 1;exit;print 2;print 3}'
1

如上所示,上圖中第一條命令中,執行了多個動作(多條語句),上圖中的第二條命令中,也執行了多個動作,但是當在awk中執行了exit語句以後,之後的所有動作都不會再被執行,相當於退出了整個awk命令。

其實,這樣描述exit的作用並不準確,因為,當在awk中使用了END模式時,exit的作用並不是退出整個awk命令,而是直接執行END模式中的動作,示例如下。

[root@server01 ~]# cat test9
1
2
3
[root@server01 ~]# awk 'BEGIN{print "Start"}{print $0}END{print "Over"}' test9
Start
1
2
3
Over
[root@server01 ~]# awk 'BEGIN{print "Start";exit}{print $0}END{print "Over"}' test9
Start
Over

如上所示,當awk中使用了END模式時,如果執行了exit語句,那麼exit語句之後的所有動作都將不會再被執行,END模式中的動作除外。

換句話說就是,當執行了exit語句後,如果使用了END模式,將直接執行END模式中的動作,其他動作將不會被執行,如果沒有使用END模式,當執行了exit語句後,將直接退出整個awk命令。

在awk中,除了能夠使用"exit命令"結束"整個awk",還能夠使用"next命令"結束"當前行",什麼意思呢?我們慢慢聊。

在前文中,我們提到過,awk是逐行對文字進行處理的,也就是說,awk會處理完當前行,再繼續處理下一行,那麼,當awk需要處理某一行文字的時候,我們能不能夠告訴awk :"不用處理這一行了,直接從下一行開始處理就行了"。

沒錯,使用next命令即可讓awk直接從下一行開始處理,換句話說就是,next命令可以促使awk不對當前行執行對應的動作,而是直接處理下一行,示例如下。

[root@server01 ~]# awk '{if(NR==1){next};print $0}' test9
2
3

其實,next與continue有些類似,只是,continue是針對"迴圈"而言的,continue的作用是結束"本次迴圈",而next是針對"逐行處理"而言的,next的作用是結束"對當前行的處理",從而直接處理"下一行",其實,awk的"逐行處理"也可以理解成為一種"迴圈",因為awk一直在"迴圈"處理著"每一行",不是嗎?