我可以在需要正则表达式的地方使用存储正则表达式的变量吗?

我可以在需要正则表达式的地方使用存储正则表达式的变量吗?

在 Awk 中,当我将正则表达式存储在变量中时,我可以在需要正则表达式的地方使用该变量吗?

Aho 的 AWK 编程语言 说

请注意,字符串匹配模式

/Asia/ 

是一个简写

$O ~ /Asia/

我有一个文本文件:

$ cat f1
line 1; li
ne
2
line 3
lin
e 4

为什么以下两种方式有效

$ awk -v pat='in' '{if (match($0, pat)) print $0; } ' f1
line 1; li
line 3
lin
$ awk -v pat='in' ' $0 ~ pat {print $0} ' f1
line 1; li
line 3
lin

而以下没有

$ awk -v pat='in' ' pat {print $0} ' f1
line 1; li
ne
2
line 3
lin
e 4

谢谢。

答案1

只有/foo/单独是 的缩写$0 ~ /foo/

... ~ /.../or match(/.../, ...)... 中,它只是正则表达式的某种形式的引用运算符,而在其他上下文中,它更多的是解析为数字(0 或 1)的运算符。

这种双重含义可能有点令人困惑。中存在很多双重含义/歧义awk

/foo/根据是否与正则表达式$0匹配而扩展为 1 或 0 foo,但当恰好匹配时则"1" ~ /foo/不是,这里不再缩写为。在或 的情况下,您会看到不同实现的行为有所不同。"1" ~ "1"$0foo/foo/($0 ~ /foo/)"1" ~ (/foo/)"1" ~ +/foo/

var只是var

var如果变量是数字或数字字符串并解析为非零数字,或者它是字符串并解析为非空字符串,则 as 条件表示 true。

用 声明的变量-v var=value属于那些可能被视为数字字符串的变量,如果它们看起来像数字和字符串。

awk -v var=in 'var {print "x"}'

x为每条记录打印,因为in它看起来不像数字,也不是空字符串。

awk -v var=0 'var {print "x"}'

不会打印x,同时:

awk 'BEGIN{var = "0"}; var {print "x"}'

将打印显式声明为字符串变量的x每条记录。var因此,尽管它看起来像一个数字,但它并不被视为数字。

这是双重含义中的另一种。根据上下文,变量可以被视为数字或字符串。另请参阅>,根据上下文被视为比较运算符或重定向运算符(这又是几种不明确的情况,其中行为在实现之间有所不同)。

请注意,您还可以执行以下操作:

awk '{print /foo/ + /bar/}'

这与以下内容相同:

awk '{print ($0 ~ /foo/) + ($0 ~ /bar/)}'

但如果使用串联而不是+

awk '{print /foo/ /bar/}'

这不起作用,因为/RE/运算符和/除法运算符之间再次存在歧义。如有疑问,请使用括号:

awk '{print (/foo/) (/bar/)}'

顺便说一句,您应该避免使用-v存储正则表达式或任何可能包含反斜杠的内容,因为 ANSI 转义序列在其中扩展(使用 GNU awk4.2 或更高版本,以 开头@/和结尾的值/也是一个问题)。相反,您应该使用环境变量:

RE='\.txt$' awk '$0 ~ ENVIRON["RE"] {...}'

例如。

相关内容