awk:如果没有模式匹配,则为“默认”操作?

时间:2013-07-24 10:17:30

标签: awk

我有一个awk脚本,它会检查很多可能的模式,为每个模式做一些事情。我希望在没有任何模式匹配的情况下完成某些事情。就像这样:

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

当然,“DEFAULT”行没有awk语法,我想知道是否有这样的语法(就像许多编程语言中的swtich / case语句一样)。

当然,我总是可以在每个动作之后添加一个“next”命令,但是如果我有很多动作,这是很乏味的,更重要的是,它阻止我将该行与两个或多个模式匹配。

5 个答案:

答案 0 :(得分:12)

您可以使用否定运算符!反转匹配,例如:

!/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 :(得分:9)

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

使用“break”或“next”作为/,如同其他编程语言一样。

或者,如果你喜欢使用旗帜:

$ 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

这并不像真正的“默认”那样具有相同的语义,但是这样的用法可能会产生误导。我通常不会提倡使用全大写变量名,但是小写“default”会与gawk关键字冲突,因此将来不会将脚本移植到gawk。

答案 2 :(得分:3)

如上所述,星期二,我对Awk中的标准方法的理解是将每个备选方案放在第二位,然后采取无模式的最终行动。

/pattern1/ { action1; next }
/pattern2/ { action2; next }
{ default-action }

下一条语句将保证所讨论的行不再考虑任何模式。如果前面的事件不发生,则默认动作将始终发生(由于所有后续的语句)。

答案 3 :(得分:1)

在awk中没有针对DEFAULT-Branch的“免维护”解决方案。

我建议的第一种可能性是使用'next'语句完成模式匹配的每个分支。所以这就像一个休息声明。在最后添加一个匹配所有内容的最终操作。所以这是DEAFULT分支。

另一种可能性是: 为每个具有模式匹配的分支设置一个标志(即您的非默认分支) 例如使用NONDEFAULT = 1;

开始您的操作

在末尾添加最后一个操作(默认分支)并定义一个条件NONDEFAULT == 0 instaed of reg expression match。

答案 4 :(得分:0)

一个相当干净,便携的解决方法是使用if语句:

而不是:

pattern1 { action1 }

pattern2 { action2 }    
...

可以使用以下内容:

{    
    if ( pattern1 ) { action1 }

    else if ( pattern2 ) { action2 }

    else { here is your default action }
}

如上所述,GNU awk有switch语句,但其他awk实现没有,所以使用switch是不可移植的。