我最近在命令行上遇到一些正则表达式时遇到麻烦,发现为了匹配反斜杠,可以使用不同数量的字符。此数字取决于用于正则表达式的引号(无,单引号,双引号)。请参阅以下bash会话了解我的意思:
echo "#ab\\cd" > file
grep -E ab\cd file
grep -E ab\\cd file
grep -E ab\\\cd file
grep -E ab\\\\cd file
#ab\cd
grep -E ab\\\\\cd file
#ab\cd
grep -E ab\\\\\\cd file
#ab\cd
grep -E ab\\\\\\\cd file
#ab\cd
grep -E ab\\\\\\\\cd file
grep -E "ab\cd" file
grep -E "ab\\cd" file
grep -E "ab\\\cd" file
#ab\cd
grep -E "ab\\\\cd" file
#ab\cd
grep -E "ab\\\\\cd" file
#ab\cd
grep -E "ab\\\\\\cd" file
#ab\cd
grep -E "ab\\\\\\\cd" file
grep -E 'ab\cd' file
grep -E 'ab\\cd' file
#ab\cd
grep -E 'ab\\\cd' file
#ab\cd
grep -E 'ab\\\\cd' file
这意味着:
- 没有引号,我可以将反斜杠与4-7个实际反斜杠匹配
- 用双引号,我可以将反斜杠与3-6个实际反斜杠匹配
- 使用单引号,我可以将反斜杠与2-3个实际反斜杠匹配
我知道shell会忽略一个额外的反斜杠(来自bash手册页):
“无引号的反斜杠(\)是转义字符。它保留后面的下一个字符的文字值”
这不适用于单引号示例,因为没有在单引号中进行转义。
grep命令会忽略另一个反斜杠(“ \ c”只是转义为“ c”,但这与“ c”相同,因为“ c”在正则表达式中没有特殊含义)。
这解释了带单引号的示例的行为,但是我并不真正理解其他两个示例,尤其是为什么非引号双引号字符串之间存在差异。
同样,bash手册页中的一句话:
“用双引号引起来的字符会保留所有引号内的字符的字面值,但$,`,\和启用历史扩展的情况除外!”。
我对GNU awk(例如awk /ab\cd/{print} file
)尝试了相同的结果。
但是,Perl显示了不同的结果(例如使用perl -ne
"/ab\\cd/"\&\&print file
):
- 没有引号,我可以将反斜杠与4-5个实际反斜杠匹配
- 使用双引号,我可以将反斜杠与3-4个实际反斜杠匹配
- 使用单引号,我可以将一个反斜杠与2个实际反斜杠匹配
谁能解释grep和awk命令行上非引号和双引号正则表达式字符串之间的区别?我对解释Perl的行为不感兴趣,因为我通常不使用Perl单行代码。
printf "\ntest"
即使"\n"
应该已经被"n"
shell 转换为双引号,但应该在外壳“ test”之前插入换行符(因此,预期结果应该是,对于“ \ ntest”,“ ntest”。我们应该养成写的习惯:printf "\\ntest"
或printf '\ntest'
,但是不知何故,我看到很多脚本依赖于怪异性