2013-07-24 38 views
8

我有一個awk腳本,它檢查很多可能的模式,爲每個模式做一些事情。如果沒有匹配的模式,我想要做的事情。即是這樣的:awk:如果沒有模式匹配,「默認」動作?

/pattern 1/ {action 1} 
/pattern 2/ {action 2} 
... 
/pattern n/ {action n} 
DEFAULT {default action} 

其中當然,「默認」行沒有awk的語法和我想知道是否有這樣的語法(如存在通常是馬桶蓋/ case語句在許多編程語言)。

當然,我總是可以在每個動作之後添加一個「下一個」命令,但是如果我有很多動作,這很乏味,更重要的是,它會阻止我將該行匹配到兩個或更多個模式。

回答

11

你可以使用否定運算符!所以像反轉匹配:

!/pattern 1|pattern 2|pattern/{default action} 

但是,這對於n>2非常討厭。另外,您可以使用一個標誌:

{f=0} 
/pattern 1/ {action 1;f=1} 
/pattern 2/ {action 2;f=1} 
... 
/pattern n/ {action n;f=1} 
f==0{default action} 
1

沒有在AWK一個DEFAULT支行沒有「免費maintanance」的解決方案。

我建議的第一種可能性是用「下一個」語句完成模式匹配的每個分支。所以這就像一個突破聲明。在結尾處添加一個匹配所有內容的最終操作。所以它是DEAFULT分支。

另一種可能性是: 爲具有模式匹配的每個分支(即,您的非默認分支) 例如 設置標誌。用NONDEFAULT = 1開始你的動作;

在末尾添加最後一個動作(默認分支),並定義一個條件NONDEFAULT == 0在reg表達式匹配的情況下。

+0

除了提示使用'next'的錯誤之外,這與我的回答有何不同呢? –

+0

ooops - 你的權利 - 對不起。 – tue

7

GNU AWK有switch語句:

$ cat tst1.awk 
{ 
    switch($0) 
    { 
    case /a/: 
     print "found a" 
     break 

    case /c/: 
     print "found c" 
     break 

    default: 
     print "hit the default" 
     break 
    } 
} 

$ cat file 
a 
b 
c 
d 

$ gawk -f tst1.awk file 
found a 
hit the default 
found c 
hit the default 

或者與任何AWK:

$ cat tst2.awk 
/a/ { 
    print "found a" 
    next 
} 

/c/ { 
    print "found c" 
    next 
} 

{ 
    print "hit the default" 
} 

$ awk -f tst2.awk file 
found a 
hit the default 
found c 
hit the default 

使用 「破發」 或 「下一個」 是/當你想,就像在其他編程語言。

或者,如果你喜歡使用標誌:

$ cat tst3.awk 
{ DEFAULT = 1 } 

/a/ { 
    print "found a" 
    DEFAULT = 0 
} 

/c/ { 
    print "found c" 
    DEFAULT = 0 
} 

DEFAULT { 
    print "hit the default" 
} 

$ gawk -f tst3.awk file 
found a 
hit the default 
found c 
hit the default 

這不是exaclty相同的語義作爲一個真正的「默認」,但這樣它的用法一樣,可能會產生誤導。我通常不會主張使用全大寫變量名,但小寫「default」會與gawk關鍵字衝突,因此腳本將來不會移植到gawk。

0

一個相當乾淨的,便攜的解決方法是使用if聲明:

相反的:

pattern1 { action1 } 

pattern2 { action2 }  
... 

一個可以使用下列內容:

{  
    if (pattern1) { action1 } 

    else if (pattern2) { action2 } 

    else { here is your default action } 
} 

如上所述,GNU awk有開關語句,但其他awk實現不這樣做,所以使用開關將不可移植。