use*_*539 5 shell grep bash quoting
我可以看到 GNU Grep 中的某些模式可以包含在括号中,而某些其他模式则不需要。例如,匹配单词的开头只有在它被引号括起来时才有效。
user@host:~/Desktop$ grep -E '\<H' test
Hello World
user@host:~/Desktop$ grep -E \<H test
Run Code Online (Sandbox Code Playgroud)
[测试包含字符串 Hello World]
但是匹配文件的结尾和开头不需要美元:
user@host:~/Desktop$ egrep d$ test
Hello World
Run Code Online (Sandbox Code Playgroud)
为什么会这样?规则是什么?
引号由外壳展开,它们决定了grep看到的内容。
使用grep -E '\<H',单引号之间的字符按字面传递,因此 grep 会看到\<H包含单词开头 anchor的正则表达式\<。
使用grep -E \<H,反斜杠字符删除<了 shell中的特殊含义,并grep看到了正则表达式<H。您会看到类似<Hello>.
使用grep -E <H,该<字符将在 shell 中作为重定向字符具有其特殊含义,因此grep将接收H在其标准输入上调用的文件的内容。
使用grep 'd$'or grep d\$,引用美元符号,使其达到grep: 正则表达式为d$,匹配d行尾的 a 。
对于grep d$ test,$符号后面没有有效的变量名或有效的标点符号 ( ${, $()。发生这种情况时,shell 会$逐字传递符号,因此grep再次看到 regex d$。$-当它后面是一个有效的变量名(什么重要的是名称如下,如即使变量是不确定的只是扩大$PATH或$fioejsfoeij或单字符变量,如$-或$$,或在结构)${…},$(…),$((…))(也是$[…]在bash 和 zsh,以及 zsh 中的更多构造)。
shell 扩展的完整规则太复杂了,无法在一篇或十几篇文章中描述。在实践中,记住通常的情况就足够了:
\ (反斜杠) 引用下一个字符,除非它是换行符,并且反斜杠总是被去除;'…'(单引号)引用除'自身之外的每个字符;"…"(双引号)引用除"$\`, 和\双引号内的每个字符会导致后面的字符按字面意思解释,并且仅在下一个字符是特殊字符时才被剥离。