2

据我了解,在 awk 中,可以使用以下任一方法开始条件评估:

if ($0 ~ /no/) {cmd}
($0 ~ /no/) {cmd}
$0 ~ /no/ {cmd}
/no/ {cmd}

在通用命令行中

BEGIN {  }  (body) END {  }

我发现将 (body) 括在括号中是最合乎逻辑的,例如 {(body} (称为“括号”)。 

在 GNU awk、Ubuntu 12.04 下,如果括号括起来,则只有 4 个选项中的第一个会执行 - 至少在我的机器上(其他选项会产生语法错误)。如果我不加括号地运行该行,则只有第一个失败,其余 3 个工作正常。有人可以仔细解释为什么会这样吗?

4

2 回答 2

3

从语法上讲,一个 awk 脚本是一组规则,如以下[Ref]

pattern { action }
pattern { action }
.... 

Wherepattern是一个表达式,并且是如果评估为真(非零数字或非空字符串)action则执行的一系列命令。pattern

如果pattern省略了,那么action将对每条记录执行。

如果{ action }省略该部分,则执行默认操作,即{ print $0 }{ print }(等效)。

正如您在问题中提到的,pattern可以是BEGIN, END, ... etc 或任何其他表达式。

您的第一个示例将在块中正确执行{ action },因为它是一个命令。其他三个选项不是命令,而是pattern { action }块的组合。

于 2013-09-22T16:34:14.600 回答
3

awk 语句遵循以下规则:

PATTERN{action}

所以BEGINEND只是特殊的模式。基本上如果 PATTERN 为真,请执行以下操作{..}

PATTERN 可以是正则表达式、表达式和范围也可以是的。

空模式看起来像:

awk '{print "foo"}' input

您可以阅读http://www.gnu.org/software/gawk/manual/gawk.html第 7.1 节了解详情。

回到您的问题,如果您在 Action 部分执行了这 4 行,即 between {...}, (实际上是空模式),则只有第一行 withif是有效的条件语句。但是,如果您将匹配检查用作模式,(在 之外{..}):

if ($0 ~ /no/) {cmd} # this would ***NOT*** work, because it is statment, not valid awk expression. (I don't know how did you make it work.)

($0 ~ /no/) {cmd} # this will work, it is a boolean expression

$0 ~ /no/ {cmd} # same as above

/no/ {cmd} # this is regexp pattern, so it works too. 
于 2013-09-22T16:36:50.423 回答