grep递归文件名匹配(grep-ir“xyz”*.cpp)不起作用

grep递归文件名匹配(grep-ir“xyz”*.cpp)不起作用,grep,Grep,当 grep-ir“xyz”*递归搜索目录,并告诉我文本出现在./x/y/z/abc.cpp中 然而, grep-ir“xyz”*.cpp不提供任何结果。 第二个命令不是应该递归地grep目录中的所有cpp文件吗? 我错过了什么 Grep将在与glob模式匹配的任何目录中递归。(在您的情况下,您可能没有任何与模式“*.cpp”匹配的目录)您可以显式地指定它们:grep-ir“xyz”*.cpp*/*.cpp*/*/*/*.cpp*/*/*/*.cpp等。您还可以使用--include选项(参见下

当 grep-ir“xyz”*递归搜索目录,并告诉我文本出现在./x/y/z/abc.cpp中 然而, grep-ir“xyz”*.cpp不提供任何结果。 第二个命令不是应该递归地grep目录中的所有cpp文件吗?
我错过了什么

Grep将在与glob模式匹配的任何目录中递归。(在您的情况下,您可能没有任何与模式“*.cpp”匹配的目录)您可以显式地指定它们:
grep-ir“xyz”*.cpp*/*.cpp*/*/*/*.cpp*/*/*/*.cpp
等。您还可以使用--include选项(参见下面的示例)

如果您使用的是GNU grep,那么您可以使用以下内容:

grep -ir --include "*.cpp" "xyz" .
上面的命令表示从当前目录开始递归搜索,忽略模式上的大小写,只搜索与glob模式“*.cpp”匹配的文件

如果您在其他Unix平台上,您可以使用:

find ./ -type f -name "*.cpp" -print0 | xargs -0 grep -i "xyz"
如果确定所有文件的名称中都没有空格,则可以省略要查找的
-print0
参数,以及要查找的
-0
参数

上面的命令说明了以下内容:查找当前目录(./)下与名称glob/通配符“*.cpp”(-name“*.cpp”)匹配的所有文件(-type f),然后将它们打印出来,并用null(-print0)分隔。找到的文件列表应写入下一个命令:xargs的stdin。xargs应该读取stdin(默认行为)并将其输入拆分为null(-0),然后在该文件列表上使用指定选项(grep-i“xyz”)调用grep命令

如果您有兴趣进一步了解为什么
grep-ir“xyz”*.cpp
不能按您认为的方式工作,那么您应该搜索“shell globbing”(这是一篇很好的关于该主题的第一篇文章)。我还将尝试提供一个快速的解释。当您键入命令grep-ir“xyz”*.cpp并点击回车键时,有两个程序参与执行您的命令。第一个程序是您的shell(除非您做了一些定制工作,否则您可能通常是bashshell-如果您从未听说过shell或bash,那么您应该从这里开始寻找,这里有很多好文章)。只需说shell只是一个程序,它的设计目的是让您在计算机上导航文件系统并运行其他程序。(在Windows中,双击图标启动程序或打开文件夹访问文件时,您运行的程序是explorer.exe,它是Windows图形shell)。因此,当您在运行grep之前键入命令grep-ir“xyz”*.cpp时,shell将处理读取您的命令并执行一些操作。其中一件事就是扩展glob模式(比如
*.txt
[0-9]+.pdf
)。就像我说的,如果你想理解它,去读更多关于它的内容,但是你应该注意的是grep命令从来没有看到
*.cpp
。发生的情况是,shell在当前目录中查找名称与模式
*.cpp
匹配的任何文件或目录,然后在运行grep命令之前在命令行中替换它们。(如果它没有找到任何匹配项,那么它将把
*.cpp
留在那里,grep将看到它,但是grep因为通常不进行全局匹配,所以这对您没有任何帮助)


或者,当您键入
grep-ir“xyz”*
时,shell会用当前目录中每个文件和目录的名称替换
*
(因为
*
匹配任何内容)。假设您有一个包含file1、file2、dir1和dir2的目录,那么shell将执行其替换,然后执行一个类似于以下内容的命令
grep-ir“xyz”file1 file2 dir1 dir2
,这意味着grep将在file1和file2中搜索字符串为xyz的行,由于
-ir
,它还递归地搜索dir1和dir2,并搜索找到该字符串的任何文件。最后,如果您已经遵循了我到目前为止所说的所有内容,那么对您来说,grep确实有一种在递归搜索中使用glob模式的方法,即使用
--include
选项,正如我前面描述的命令中所述:
grep-ir--include“*.cpp”“xyz”。
,在该命令中,我们将
*.cpp
放在引号中的原因是为了防止shell在运行该命令之前尝试扩展glob模式。

当然。但是为什么grep-ir“xyz”*.cpp在grep-ir“xyz”*工作时不工作呢?我已经更新了答案:grep将只在命令行上指定的任何目录中递归。它不进行递归文件名匹配。
--include
选项用于递归文件名匹配。@EtanReisner谢谢,我已经更新了GNU grep的答案。我不记得是否有包含选项。我在一个多Unix环境中工作,对查找选项了如指掌。
*
扩展到当前目录中的所有目录和文件,因此
grep
能够找到字符串
*.cpp
仅来自与模式匹配的文件和目录的greps
*.cpp
,目录
x
与glob
*.cpp
不匹配,因此grep没有尝试在其中搜索。