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

Gad*_*i A 10 awk

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

/pattern 1/ {action 1}
/pattern 2/ {action 2}
...
/pattern n/ {action n}
DEFAULT {default action}
Run Code Online (Sandbox Code Playgroud)

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

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

Chr*_*our 12

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

!/pattern 1|pattern 2|pattern/{default action}
Run Code Online (Sandbox Code Playgroud)

但这非常讨厌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}
Run Code Online (Sandbox Code Playgroud)


Ed *_*ton 10

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
Run Code Online (Sandbox Code Playgroud)

或者任何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
Run Code Online (Sandbox Code Playgroud)

使用"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
Run Code Online (Sandbox Code Playgroud)

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


小智 5

正如上面 tue 所提到的,我对 awk 中标准方法的理解是将 next 放在每个选项上,然后在没有模式的情况下进行最终操作。

/pattern1/ { action1; next }
/pattern2/ { action2; next }
{ default-action }
Run Code Online (Sandbox Code Playgroud)

下一个语句将保证不再考虑相关行的模式。如果前面的动作没有发生,默认动作将始终发生(感谢所有接下来的语句)。