为什么
echo foo bar..baz bork | awk 'BEGIN{RS=".."} {gsub(OFS,"\t");}1'
似乎与
做同样的事情echo foo bar..baz bork | awk 'BEGIN{RS=".."} {gsub(OFS,"\t");} {print;}'
事实上,任何不为零的数字(包括小数和负数)都会做同样的事情。但是,不使用文本字符或使用零来删除数字。我没有在任何地方看到这个记录,虽然我可能错过了一些东西。
答案 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}'
打印 a
和b
,因为1
和2
非零且评估为true
。由于c
评估为0
,因此不会打印false
。