【问题标题】:grep regex with backtick matches all lines带有反引号的 grep 正则表达式匹配所有行
【发布时间】:2015-10-23 00:35:59
【问题描述】:
$ cat file
anna
amma
kklks
ksklaii

$ grep '\`' file
anna
amma
kklks
ksklaii

为什么?匹配效果如何?

【问题讨论】:

  • 请注意,MacOS grep 做了您认为应该做的事情; GNU 显示了这种行为。另请注意,删除反斜杠将使其工作。因此,当转义反引号时,GNU grep 中会发生一些奇怪的事情(AFAIK 应该等同于普通反引号,但不是)。
  • 另请注意,添加 -P 选项(使用 PCRE 引擎)将使其正常运行。所以我倾向于认为这是 GNU grep 解析正则表达式中的一个错误。

标签: regex bash grep gnu-coreutils


【解决方案1】:

这似乎是正则表达式的 GNU 扩展。反引号 ('\`') 锚点匹配主题字符串的开头,这解释了为什么它匹配所有行。 OS X 显然没有实现 GNU 扩展,这可以解释为什么您的示例与那里的任何行都不匹配。见http://www.regular-expressions.info/gnu.html

如果您想在 GNU 扩展生效时匹配实际的反引号,这对我有用:

grep '[`]' file

【讨论】:

    【解决方案2】:

    twm's answer 提供了关键指针,但请注意,它是 序列 \`,而不是 ` 本身充当 GNU 正则表达式中的输入起始锚。

    因此,要匹配指定为 单引号 shell 字符串的正则表达式中的文字反引号,您根本不需要任何转义,GNU @ 也不需要987654324@ 或 BSD/macOS grep:

    $ { echo 'ab'; echo 'c`d'; } | grep '`'
    c`d
    

    当使用 双引号 shell 字符串 - 对于正则表达式,您应该避免,原因如下:变得显而易见 - 事情变得更加复杂,因为您必须为了 shell 将 ` 转义,以便将其作为文字传递给 grep:

    $ { echo 'ab'; echo 'c`d'; } | grep "\`"
    c`d
    

    请注意,在 shell 解析 "..." 字符串后,grep 仍然只能看到 `。

    使用 GNU grep 重新创建带有 双引号 字符串的原始命令:

    $ { echo 'ab'; echo 'c`d'; } | grep "\\\`" # !! BOTH \ and ` need \-escaping
    ab
    c`d
    

    同样,在 shell 的字符串解析之后,grep 只看到 \`,对于 GNU,grep 是输入的起始锚点,因此所有输入行都匹配。

    • 另请注意,由于grep 逐行处理输入,\` 与^ 开头的锚点具有相同的效果line;但是,对于多行输入 - 例如,如果您使用 grep -z 一次读取所有行 - \` 仅匹配整个字符串的开头。

    对于 BSD/macOS grep,\` 只是转义文字 `,因此它只匹配包含该字符的输入行。

    【讨论】:

      猜你喜欢
      • 2011-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多