我有一个awk脚本,它会检查很多可能的模式,为每个模式做一些事情。我希望在没有任何模式匹配的情况下完成某些事情。就像这样:
/pattern 1/ {action 1}
/pattern 2/ {action 2}
...
/pattern n/ {action n}
DEFAULT {default action}
当然,“DEFAULT”行没有awk语法,我想知道是否有这样的语法(就像许多编程语言中的swtich / case语句一样)。
当然,我总是可以在每个动作之后添加一个“next”命令,但是如果我有很多动作,这是很乏味的,更重要的是,它阻止我将该行与两个或多个模式匹配。
答案 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是不可移植的。