为什么不能将常量正则表达式放在 gawk 中 ~ 运算符的左侧?

为什么不能将常量正则表达式放在 gawk 中 ~ 运算符的左侧?

为什么使用 gawk 时不能在 ~ 运算符的左侧放置正则表达式?

例如,给定以下文件,其中字段由制表符 (\t) 分隔:

$ cat cats
siberian    1970    73  2500
shorthair   1999    60  3000
longhair    1998    102 9859
scottish    2001    30  6000

如果我使用 gawk 查找记录,它会起作用:

$ gawk '$1 ~ /h/' cats
shorthair   1999    60  3000
longhair    1998    102 9859
scottish    2001    30  6000

但是,如果我移动操作数 $1 和 /h/ ,它不会:

$ gawk '/h/ ~ $1' cats
gawk: cmd. line:1: warning: regular expression on left of `~' or `!~' operator

~ 运算符的 gawk 手册页显示:

正则表达式匹配,否定匹配。注意:不要在 ~ 或 !~ 的左侧使用常量正则表达式 (/foo/)。仅在右侧使用。表达式 /foo/ ~ exp 与 (($0 ~ /foo/) ~ exp) 具有相同的含义。这通常不是预期的。

我不明白表达式 /foo/ 是如何被评估为 ($0 ~ /foo/) 的,而且这似乎只意味着较弱的短语“如果你在左边放置一个常量正则表达式,就会发生坏事”,但它并没有实际上并不意味着“如果将常量正则表达式放在左侧,则 gawk 的行为是未定义的,因为它没有被编程为以这种方式使用”。

我基本上不明白运算符 ~ 内部是如何评估的。

答案1

引用 awk 的 POSIX 规范:

~当 ERE 标记在除or运算符右侧!~或下述内置函数参数之一之外的任何上下文中显示为表达式时,结果表达式的值应等效于:

$0 ~ /ere/

这(与默认为 的操作相结合{ print })就是为什么您可以通过执行 来用作替代awk品。grepawk '/b/' <file

所以,答案只是“它被定义为以这种方式工作”。 /ere/被定义为$0 ~ /ere/除非在某些情况下,并且/ere/ ~ $1不是特殊情况之一,因此它被评估为($0 ~ /ere/) ~ $1

相关内容