我有一个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"]
?
该
~
运算符进行模式匹配,将右手操作数视为(扩展)正则表达式,将左手操作数视为字符串。POSIX说:So
ENVIRON["patt"]
被视为正则表达式,如果您不希望它们具有其常规 ERE 含义,则需要对ERE 中的所有特殊字符进行转义。请注意,这不是使用
$0
orENVIRON["name"]
,而是使用波浪号的左侧和右侧。这会将输入行 (in$0
) 作为匹配的正则表达式:\
正则表达式中的A转义后面的字符,或引入转义序列。要将文字\
与正则表达式匹配,这是~
运算符在 中所做的awk
,需要使用\\
(您在问题的最后一个示例中执行此操作)。在字符串比较中,这不是必需的。