在 awk 中使用波浪号 ~ 运算符时需要在哪里转义序列?

αғs*_*нιη 6 awk escape-characters

我有一个pattern具有以下值的变量:

\"something//\\anotherthing'
Run Code Online (Sandbox Code Playgroud)

和一个包含以下内容的文件:

\"something//\\anotherthing'
\"something//\\anotherthing
\"something/\anotherthing'
\"something\anotherthing'
\\"something\/\/\\\\anotherthing'
Run Code Online (Sandbox Code Playgroud)

当我将从文件中读取的一行与使用==运算符的环境中的模式进行比较时,我得到了预期的输出:

patt="$pattern" awk '{print $0, ENVIRON["patt"], ($0 == ENVIRON["patt"]?"YES":"NO") }'  OFS="\t" file
\"something//\\anotherthing'    \"something//\\anotherthing'    YES
\"something//\\anotherthing     \"something//\\anotherthing'    NO
\"something/\anotherthing'      \"something//\\anotherthing'    NO
\"something\anotherthing'       \"something//\\anotherthing'    NO
\\"something\/\/\\\\anotherthing'       \"something//\\anotherthing'    NO
Run Code Online (Sandbox Code Playgroud)

但是当我对~操作员做同样的事情时,测试永远不会匹配。(我预计YES在第一行,如上所述):

patt="$pattern" awk '{print $0, ENVIRON["patt"], ($0 ~ ENVIRON["patt"]?"YES":"NO") }'  OFS="\t" file
\"something//\\anotherthing'    \"something//\\anotherthing'    NO
\"something//\\anotherthing     \"something//\\anotherthing'    NO
\"something/\anotherthing'      \"something//\\anotherthing'    NO
\"something\anotherthing'       \"something//\\anotherthing'    NO
\\"something\/\/\\\\anotherthing'       \"something//\\anotherthing'    NO
Run Code Online (Sandbox Code Playgroud)

要通过~比较解决问题,我需要对转义符进行双重转义:

patt="${pattern//\\/\\\\}" awk '{print $0, ENVIRON["patt"], ($0 ~ ENVIRON["patt"]?"YES":"NO") }'  OFS="\t" file
\"something//\\anotherthing'    \\"something//\\\\anotherthing' YES
\"something//\\anotherthing     \\"something//\\\\anotherthing' NO
\"something/\anotherthing'      \\"something//\\\\anotherthing' NO
\"something\anotherthing'       \\"something//\\\\anotherthing' NO
\\"something\/\/\\\\anotherthing'       \\"something//\\\\anotherthing' NO
Run Code Online (Sandbox Code Playgroud)

请注意ENVIRON["patt"]第二列中打印结果的双重转义。

题:

使用波浪号比较运算符时,awk中的转义序列在哪里发生~?在$0(或$1,,$2...)或在ENVIRON["variable"]

mur*_*uru 8

~操作者确实模式匹配,处理右手操作数作为(扩展)的正则表达式,以及左手一个为字符串。POSIX说:

通过使用两个正则表达式匹配运算符之一,可以将正则表达式与特定字段或字符串进行匹配,'~'"!~"。这些运算符应将其右侧操作数解释为正则表达式,并将其左侧操作数解释为字符串。

SoENVIRON["patt"]被视为正则表达式,如果您不希望它们具有常规 ERE 含义,则需要将ERE 中的所有特殊字符都进行转义。


请注意,这不是关于使用$0or ENVIRON["name"],而是波浪号的左右两侧。这将把输入行 (in $0) 作为正则表达式来匹配:

str=foobar awk 'ENVIRON["str"] ~ $0 { 
     printf "pattern /%s/ matches string \"%s\"\n", $0, ENVIRON["str"] }'
Run Code Online (Sandbox Code Playgroud)