我使用“bash”外壳并在文件上执行下面的“awk”命令,文件记录用括号、冒号、括号等不同字符分隔,如下示例记录
...(field#13[field#14:]]:filed#18[filed#19)[...
但是,当我使用单转义“\”转义“] [”时,awk 命令失败,我必须双转义 '\\' 括号才能获得预期的结果,它需要如何使用双转义括号(在 'csh ' 外壳是一样的)?
awk -F"[\\[\\]:)(]" '{print $18}' inFile
filed#18
还请注意这一点,我知道我可以用双重转义 '\\' 来逃避它们,如下所示,我只想知道为什么对于括号这是强制性的?
awk -F"[\\[\\]\\:\\)\\(]" '{print $18}' inFile
filed#18
即使使用信号转义也会发出警告(括号除外),但仍然命令执行和结果来了,谢谢
awk -F '[\\[\\]\:\)\(]' '{print $18}' inFile
awk: warning: escape sequence `\:' treated as plain `:'
awk: warning: escape sequence `\)' treated as plain `)'
awk: warning: escape sequence `\(' treated as plain `('
filed#18
这里有多个级别的引用/转义。首先,您将
FS
正则表达式 (-F "[\\[\\]\:\)\(]"
) 放在双引号中。这就是发出警告的原因:虽然单引号起作用:
这是因为双引号中的任何内容首先由 shell 扩展。因此,shell 首先扩展
\\[
为\[
,然后将其传递给 awk。您可以通过以下方式看到这种情况set -x
:正如你在上面看到的,shell 吃了第一个逃逸。所以根本不要
"
在这里使用。下一个问题是 awk 本身解释了两次转义。因为它
-F
可以接受特殊的转义,比如\t
等等\r
,所以它会首先尝试读取\[
一个单一的转义字符。因为\[
是相同的[
(不像,说\n
哪个不一样,n
因为\n
是换行符),它会给你一个警告信息,解释它被\[
视为[
.因此,您需要第一次转义来转义
\
自身,第二次转义来转义[
. 换句话说,在 中\\[
,第一个\
正在逃避第二个\
,因此awk
最终收到的是\[
。如果你考虑这样的事情可能会更容易理解:
上面的最后一个例子是最能说明问题的。由于要回显的字符串是用双引号括起来的,所以它首先由外壳扩展(吃掉一个
\
),然后是echo -e
(吃掉另一个\
),最后打印为文字\t
。