【问题标题】:What does a number do after curly braces?花括号后面的数字有什么作用?
【发布时间】:2017-09-16 08:28:41
【问题描述】:

为什么

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

似乎和

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

?

事实上,任何不为零的数字(包括小数和负数)都会做同样的事情。但是,省略数字、使用文本字符或使用零不会打印任何内容。尽管我可能遗漏了一些东西,但我没有在任何地方看到此文档。

【问题讨论】:

  • 您可以缩短代码一些:awk '-v RS=".." {gsub(OFS,"\t")}1' 或将变量放在代码后面 awk '{gsub(OFS,"\t")}1' RS=".."

标签: awk


【解决方案1】:

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

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

当然,与 BEGIN 和 END 模式相关的动作是经过特殊处理的。

【讨论】:

  • 有道理。不知何故,我认为 AWK 将其解析为先前操作语句的一部分,有点像 d 在 sed 中的使用方式。
  • 您可能需要注意,您的示例中的所有分号都是有效的,但都是多余的。
  • 我知道大多数教科书将其称为pattern,但恕我直言,将其称为condition 更有意义,因为它确实是这样。我相信有一个模式是 1970 年代 awk 的初衷,但那是很久很久以前...
  • 任何数字都可以使用52345,甚至负数也可以使用-54,但大多数使用1
  • 一个省略的动作默认为{print $0}(又名{print}),但省略1不起作用,为什么?似乎1 不等于{print;}。不过,1{print;} 的输出是相同的。这真的很令人困惑,你能解释一下吗?
【解决方案2】:

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

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

似乎相当于

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

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

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

这是一个我认为更好地展示了awk 使用的condition {action} 格式的示例:

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

ab 被打印,因为 12 不为零并且计算结果为 truec 未打印,因为 0 的计算结果为 false

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-08
    • 2013-10-14
    • 2014-12-05
    • 1970-01-01
    相关资源
    最近更新 更多