Answers:
这取决于应用程序。在您的示例中,[
必须引用,grep
但不能引用echo
。
对于外壳(根据POSIX规范):
引用用于将某些字符或单词的特殊含义删除。引用可用于保留下一段中特殊字符的字面含义,防止保留字被这样识别,并防止在此处文档处理中进行参数扩展和命令替换(请参见此处文档)。
如果应用程序使用以下字符表示自己,则应引用这些字符:
| & ; < > ( ) $ ` \ " ' <space> <tab> <newline>
并且在某些情况下可能需要引用以下内容。也就是说,根据这些字符在IEEE Std 1003.1-2001的其他部分中所述的条件,这些字符可能是特殊的:
* ? [ # ˜ = %
各种引用机制是转义字符,单引号和双引号。本文是另一种报价形式。请参阅此处文档。
特定程序(使用正则表达式,perl,awk)可能对转义有其他要求。
正则表达式有多种类型,特殊字符集取决于特定类型。其中一些描述如下。在所有情况下,特殊字符都由反斜杠转义\
。例如,与[
您写的匹配\[
。或者,^
可以通过将字符(除外)一一包围在方括号之间来进行转义[[]
。
在某些情况下,^
特殊字符(例如,(子)表达式开头的特殊字符)可以在所有上下文中转义。
就像其他人写道:在shell中,如果不将表达式括在单引号之间,则必须在已经转义的正则表达式中另外转义shell的特殊字符。示例:'\['
您可以用bash这样的Bourne兼容shell 编写\\[
(或者:"\["
或"\\["
),但这是另一回事了。
grep
,sed
.[\
*^$
"$(printf '%s' "$string" | sed 's/[.[\*^$]/\\&/g')"
grep -E
,GNU:sed -r
,* BSD:sed -E
.[\(
*^$)+?{|
"$(printf '%s' "$string" | sed 's/[.[\*^$()+?{|]/\\&/g')"
Shell可以在命令执行之前转换命令行。外壳程序和都grep
可以使用引号删除某些字符的特殊含义。但是,grep
shell具有不同的特殊字符。而且,在执行命令之前,shell会删除不是由现有扩展引起的未转义的特殊字符。
echo '[]' | grep '[]'
外壳程序将参数传递[]
给grep
,并被解析为格式不正确的括号表达式grep
。
echo '[]' | grep \[]
在上面,我们可以看到类似的情况。反斜杠被删除,并[]
作为参数传递给grep
。grep
识别格式不正确的括号表达式。
echo '[]' | grep '\[]'
最后,在这种情况下,引号被外壳删除,并\[]
作为参数传递给,grep
但在这种特殊情况下,\[
被解释grep
为文字括号。需要使用引号防止外壳将反斜杠解释为特殊字符。
¹POSIX 规范。
bash
包括)的shell中,!
仍然使用双引号将其展开,只有单引号将停止其扩展(或关闭shell选项)。