使用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 的行为是未定义的,因为它没有被编程为以这种方式使用”。
我基本上不明白操作符 ~ 是如何在内部评估的。
引用 awk 的 POSIX 规范:
当 ERE 标记在任何上下文中作为表达式出现而不是作为
~
或!~
运算符的右侧或作为下述内置函数参数之一出现时,结果表达式的值应等于:
$0 ~ /ere/
这(用行动默认为合并{ print }
)就是为什么你可以使用awk
一个grep
由只是做替补awk '/b/' <file
。
所以,答案只是“它被定义为以这种方式工作”。 /ere/
被定义为表示$0 ~ /ere/
在某些情况下除外,并且/ere/ ~ $1
不是特殊情况之一,因此它被评估为($0 ~ /ere/) ~ $1
。