在 GNU grep 正则表达式中使用引号

在 GNU grep 正则表达式中使用引号

我可以看到 GNU Grep 中的某些模式可以括在括号内,而某些其他模式则不需要。例如,仅当单词包含在引号内时,匹配单词的开头才有效。

user@host:~/Desktop$ grep -E '\<H' test
Hello World
user@host:~/Desktop$ grep -E \<H test

[测试包含字符串 Hello World]

但是匹配文件的结尾和开头不需要美元:

user@host:~/Desktop$ egrep d$ test
Hello World

为什么会这样呢?规则是什么?

答案1

引号由 shell 扩展,它们决定所grep看到的内容。

对于grep -E '\<H',单引号之间的字符按字面意思传递,因此 grep 会看到\<H包含单词开头锚点的正则表达式\<

使用 时,反斜杠字符会删除shell 中grep -E \<H的特殊含义,并看到正则表达式。您会看到像这样的行的匹配项。<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$$仅当其后跟有效的变量名时才会展开(即使该变量未定义 - 重要的是后面有一个名称,如$PATHor$fioejsfoeij或单字符变量,如$-or $$),或在结构${…}, $(…), $((…))(也可以$[…]在bash 和 zsh,以及 zsh 中的更多构造)。

shell 扩展的完整规则太复杂,无法用一篇或十几篇文章来描述。在实践中,记住通常的情况就足够了:

  • \(反斜杠)引用下一个字符,除非它是换行符,并且反斜杠始终被删除;
  • '…'(单引号)引用除'自身之外的每个字符;
  • "…"(双引号)引用除 之外的每个字符"$\`,并且\在双引号内会导致后面的字符按字面解释,并且仅在下一个字符特殊时才被删除。

答案2

首先\<由 shell 转义,其值成为文字<字符。所以传递给的正则表达式grep是 string <H,它没有特殊的含义。

如果您需要深入了解这种特定关系,您应该查阅吉尔斯的答案。

相关内容