【问题标题】:Why is grep giving unexpected result?为什么 grep 会给出意想不到的结果?
【发布时间】:2018-04-05 20:43:28
【问题描述】:

我有扩展名为 .m 和 .slx 的文件。我想使用 grep 从 svn 日志中检查修改过的 m 文件:使用

svn status | grep "M  " | grep ".m"

我明白了

M       foo.m
M       model1.slx.

我希望只看到 foo.m。但为什么我也看到了 model1.slx?它应该被第二个 grep 过滤掉。

【问题讨论】:

  • grep 使用正则表达式。 .m 表示“任何字符 (.) 后跟 m”。第二行符合这个描述;它在model1.slx 之前包含一个空格(或制表符)。您必须将.m 锚定到行尾:\.m$。使用man -s 7 regex 了解正则表达式。

标签: linux grep


【解决方案1】:

您看到的问题是因为. 是正则表达式上下文中的元字符,需要对其进行转义以剥夺其特殊含义(以匹配任何字符)。

如果您只想列出以.m.slx 结尾的文件,或者以M 开头并以.m 结尾的文件,您的要求并不明确。前者使用下面的建议,后者使用grep ^M.*\.m$

通过启用-E 扩展正则表达式支持模式,您可以只使用一个grep

svn status | grep -E '(\.m|\.slx)$' 

交替 | 运算符在 ERE 模式下默认启用,但在使用 BRE(基本正则表达式)模式时需要转义

svn status | grep '\.m$\|\.slx$'

【讨论】:

    【解决方案2】:

    . 匹配 任何 字符。对于. 字符,根据the POSIX regex rules

    匹配任何单个字符(许多应用程序不包括换行符,并且确切地将哪些字符视为换行符是特定于风味、字符编码和平台的,但可以安全地假设包含换行符)。在 POSIX 括号表达式中,点字符匹配文字点。例如,a.c 匹配“abc”等,但 [a.c] 仅匹配“a”、“.”或“c”。

    要匹配不在[] 括号中的. 字符,您需要使用\ 字符对其进行转义:

    \.m
    

    将匹配文字.m

    【讨论】:

      【解决方案3】:

      我想使用 grep 从 svn 日志中检查修改过的 m 文件:

      $ svn status | grep ^M.*\.m$
      M       foo.m
      

      即。行以M 开头并以.m 结尾。

      【讨论】:

        猜你喜欢
        • 2021-12-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-11
        • 1970-01-01
        • 1970-01-01
        • 2022-09-23
        • 2019-05-19
        相关资源
        最近更新 更多