下面这句awk代码
awk '{tempword="abc&"; gsub("&","\\\\&",tempword); print tempword }'
输出:
abc\&
我把反斜杠的数目换成1个和3个的时候,有警告:
awk: warning: escape sequence `\&' treated as plain `&'
换成两个却没有警告,不过当反斜杠为1个,2个或3个时,输出都是
abc&
请问这是怎么回事?
恭喜你踩中了 awk 的坑!
关键在于,awk 首先读取你的语句,构建一个内部的副本供执行,然后再执行构建的副本。坑爹之处在于,构建和执行的时候都会处理 反斜杠,也就是说,会有两次转义!更坑爹的是,运行时 gsub
和 sub
会采用不同的规则来处理反斜杠 !
首先是构建的规则,这个比较简单,特殊字符前带 \
会转义,非特殊字符前带 \
就表示这个字符自身。也就是说 \\
-> \
, \&
-> &
第一次转义:
\\\\&
-> \\
+\\
+ &
= \\&
\\\&
-> \\
+ \&
= \&
\\&
-> \\
+ &
= \&
\&
-> \
+ &
= &
所以我们看到,经过第一次转义后,三个反斜杠和两个反斜杠是一样的。
然后是第二次转义,这次规则不一样了,\&
表示 &
,其他 \
都不变动。(gsub
和 sub
将 \&
转成 &
,然后其他反斜杠,在替换部分都不变动,前面匹配部分还是会转义的!)
所以,第二次转义后:
\\&
-> \&
\&
-> &
&
-> &
总之,人生苦短,远离 awk !