花括号后数字有什么作用?

时间:2014-07-08 23:42:05

标签: awk

为什么

echo foo bar..baz bork | awk 'BEGIN{RS=".."} {gsub(OFS,"\t");}1'

似乎与

做同样的事情
echo foo bar..baz bork | awk 'BEGIN{RS=".."} {gsub(OFS,"\t");} {print;}'

事实上,任何不为零的数字(包括小数和负数)都会做同样的事情。但是,不使用文本字符或使用零来删除数字。我没有在任何地方看到这个记录,虽然我可能错过了一些东西。

2 个答案:

答案 0 :(得分:19)

如果您还记得,awk是一种具有一系列<pattern> <action>操作的语言。针对每一行评估每个模式(至少在概念上),并且当模式匹配时,执行该动作。可以省略模式或动作。省略的模式匹配每一行;省略的操作默认为{print $0}(又名{print})。 '模式'可能是一个简单的正则表达式匹配,或者是一些其他更复杂和一般的条件,如果要执行该操作,则必须将其评估为true(如Ed Morton中的comment所述)。

在您的示例中,1是一种模式;它评估为真。未指定操作,因此将调用默认操作,即{print}{print $0}。除零或空字符串以外的任何值都将计算为true并将调用print。 (注意,如果你提到一个未初始化的变量(例如,c),那么它会被自动处理并设置为零,因此计算结果为false。因此awk 'c' <<<"Hi"不打印任何内容。)

当然,特别处理与BEGIN和END模式相关的动作。

答案 1 :(得分:3)

我真的不喜欢这些类型的快捷方式,因为它会混淆和误导它的解析方式。就像你说的那样,

awk 'BEGIN{RS=".."} {gsub(OFS,"\t");}1'

似乎等同于

awk 'BEGIN{RS=".."} {gsub(OFS,"\t");} {print;}'

这似乎意味着1只是{print}的别名。但事实并非如此。 1与前一个括号无关。它实际上是第二个语句的一部分,它没有action,所以它使用action的默认{print}。你可以这样想它。

awk 'BEGIN{RS=".."} {gsub(OFS,"\t")}; 1!=0 {print}'

以下是我认为更好地展示condition {action}使用的awk格式的示例:

echo 'a b c' | awk '1 {print $1}; 2 {print $2}; 0 {print $3}'
打印

ab,因为12非零且评估为true。由于c评估为0,因此不会打印false