Grep 似乎没有找到我期望的文件中的所有匹配项

Grep 似乎没有找到我期望的文件中的所有匹配项

我不确定我是否没有完全理解grep,或者正则表达式是否是导致我问题的根源,所以我有两个问题。我有一个名为test.txt以下内​​容的简单测试文件:

$ cat test.txt Settings.xml blah Settings_1.xml blah Settings_2.xml

当我grep在仅包含上述测试文件的目录中运行以下命令时,它返回没有匹配项:

$ grep -ir "Settings*xml"

1)为什么通配符*没有捕捉到句点?

当我grep这样运行时:

$ grep -ir "Settings*.xml"

唯一的区别是通配符后的句点,结果是:

test.txt:Settings.xml

2)为什么grep找不到另外两个匹配项?

答案1

原因是*在正则表达式中 是一个特殊字符,表示 zero or more preceding characters。您必须转义*才能表示文字*字符\。因此在您的示例中:

grep -ir "Settings*xml"

会搜索以 开头Setting,结尾为零个或多个s字符 和的字符串xml。您的文件中没有这样的字符串,因为xml前面总是.。而这个:

grep -ir "Settings*.xml"

Setting将搜索以 开头,然后在零个或多个字母之后有零个或多个s和的字符串。.xmls

您的第一个正则表达式将匹配如下内容:

Settingssxml

答案2

其他答案解释了发生了什么,回答了你的明确问题。我的回答旨在介绍更广泛的背景。

我猜你期望*匹配零个或多个字符(任何字符)并且.字面意思是.。这适用于 shell 通配符,即如果你有文件像这样:

$ ls -1
Settings.xml
blah
Settings_1.xml
Settings_2.xml

然后(比如说,在bash)你可以这样做:

$ echo Settings*.xml
Settings.xml Settings_1.xml Settings_2.xml

您没有得到预期的结果,因为grep使用了正则表达式语法:

  • .匹配(几乎)任何字符,
  • *表示“零个或多个前面的字符”,
  • \强制按字面意思解释下一个字符。

这就是为什么你应该"Settings*.xml"使用"Settings.*\.xml"。 在这种情况下:

  • .*按照你的想法*去做,
  • \.按照您的想法.去做。

相关内容