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

Jer*_*bas 5 gawk

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

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

$ cat cats
siberian    1970    73  2500
shorthair   1999    60  3000
longhair    1998    102 9859
scottish    2001    30  6000
Run Code Online (Sandbox Code Playgroud)

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

$ gawk '$1 ~ /h/' cats
shorthair   1999    60  3000
longhair    1998    102 9859
scottish    2001    30  6000
Run Code Online (Sandbox Code Playgroud)

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

$ gawk '/h/ ~ $1' cats
gawk: cmd. line:1: warning: regular expression on left of `~' or `!~' operator
Run Code Online (Sandbox Code Playgroud)

~ 操作符的 gawk 手册页说:

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

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

我基本上不明白操作符 ~ 是如何在内部评估的。

god*_*eek 9

引用 awk 的 POSIX 规范:

当 ERE 标记在任何上下文中作为表达式出现而不是作为~!~运算符的右侧或作为下述内置函数参数之一出现时,结果表达式的值应等于:

$0 ~ /ere/

这(用行动默认为合并{ print })就是为什么你可以使用awk一个grep由只是做替补awk '/b/' <file

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