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

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

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

\"something//\\anotherthing'

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

\"something//\\anotherthing'
\"something//\\anotherthing
\"something/\anotherthing'
\"something\anotherthing'
\\"something\/\/\\\\anotherthing'

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

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

但是当我对操作员做同样的事情时~,测试永远不会匹配。 (我期望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

为了通过比较来解决问题,~我需要双重转义转义:

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

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

问题:

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

答案1

~运算符进行模式匹配,将右侧操作数视为(扩展)正则表达式,将左侧操作数视为字符串。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"] }'

答案2

\正则表达式中的A对后面的字符进行转义,或引入转义序列。要将文字\与正则表达式匹配(这就是~运算符在 中所做的事情awk),需要使用\\(您在问题的最后一个示例中执行此操作)。在字符串比较中,这是不需要的。

相关内容