来自 Gawk 的手册:
当一个规则中的 awk 语句很短时,您可能希望将多个语句放在一行中。这是通过用分号 (';') 分隔语句来实现的。这也适用于规则本身。因此,本节开头显示的程序也可以这样编写:
Run Code Online (Sandbox Code Playgroud)/12/ { print $0 } ; /21/ { print $0 }
注意:在原始 awk 语言中,要求声明同一行的规则必须用分号分隔;添加它是为了与操作中的语句处理保持一致。
但是我从/sf/ask/1418400861/看到
awk '$2=="no"{$3="N/A"}1' file
Run Code Online (Sandbox Code Playgroud)
不是$2=="no"{$3="N/A"}
和1
两个语句吗?为什么它们没有被任何东西隔开?
谢谢。
Geo*_*iou 12
很好的问题!我认为关键是:“因此,本节开头显示的程序也可以这样编写:”
不是强制用这种方式写的。这是一种替代方式。这意味着(并已在行动中证明)以下陈述都是正确的:
$ awk '/12/ { print $0 } /21/ { print $0 }' file
$ awk '/12/ { print $0 } ; /21/ { print $0 }' file
Run Code Online (Sandbox Code Playgroud)
我认为这个分号的用法是为了覆盖非常短的惯用代码,例如我们省略动作部分并且我们想在同一行上应用多个规则的情况:
$ awk '/12//21/' file
awk: cmd. line:2: /12//21/
awk: cmd. line:2: ^ unexpected newline or end of string
Run Code Online (Sandbox Code Playgroud)
在这种情况下,必须使用分号来分隔规则(=条件):
$ awk '/12/;/21/' file
Run Code Online (Sandbox Code Playgroud)
由于{action}
在两个规则/两个条件中都省略了部分,因此将为每个规则执行默认操作 ={print $0}
在gawk中,手册中的这两句话描述了这个问题:
一个动作由一个或多个 awk 语句组成,用大括号 ('{…}') 括起来。每个语句都指定了要做的一件事。语句由换行符或分号分隔。
分号是“分隔符”但不是“终止符”。
动作的唯一有效终止符是右大括号 ( }
)。
因此,跟在动作右括号 ( }
)后面的一定是其他模式{action}
在“man mawk ”中,还有一些其他描述可能有助于阐明 awk 应该做什么:
语句以换行符、分号或两者结束。语句组(例如动作或循环体)通过 { ... } 阻塞,就像在 C 中一样。块中的最后一个语句不需要终止符。
“man nawk ”是这样解释的:
先有模式,后有行动。操作语句包含在 { 和 } 中。
而且,如果您想深入了解细节,请阅读 POSIX 说明:
action : '{' newline_opt '}'
| '{' newline_opt terminated_statement_list '}'
| '{' newline_opt unterminated_statement_list '}'
;
Run Code Online (Sandbox Code Playgroud)
并搜索什么是“未终止”语句列表。
或者,更简单地,搜索Action来阅读:
任何单个语句都可以用花括号括起来的语句列表替换。应用程序应确保语句列表中的语句由 <newline> 或 <semicolon> 字符分隔。
再次: are separated by <newline> or <semicolon> characters