我尝试以以下方式在所有 .c 文件中递归搜索模式
> grep -lr search-pattern *.c
但得到的是这个作为输出
> grep: *.c: No such file or directory
当我使用这个时:
> grep -lr search-pattern *
我在具有该模式的目录中获得了大量 .c 文件。
先前的表述有何错误?
答案1
我建议使用以下--include
选项grep
:
grep -lr --include='*.c' search-pattern .
答案2
该*.c
模式由您的 shell 评估。它适用于当前目录,就像您使用 一样ls *.c
。
我认为您想要的是找到所有与*.c
模式匹配的文件(递归),然后grep
在其中进行搜索。以下是实现此目的的方法:
find . -name "*.c" -print0 | xargs --null grep -l search-pattern
它用于xargs
通过 附加搜索结果find
。
或者,使用-exec
选项来查找,例如:
find . -name "*.c" -exec grep -l search-pattern "{}" \;
另外,我不确定你是否真的想要这个-l
选项grep
。它会在第一次匹配时停止:
-l, --files-with-matches
Suppress normal output; instead print the name of each
input file from which output would normally have been
printed. The scanning will stop on the first match.
(-l is specified by POSIX.)
答案3
正如 grep 文档在 -r 选项的讨论中所述:
"If no folder name is given, grep command will search the string inside the current working directory."
因此,您的原始命令行(忽略 -l 标志):
grep -lr 搜索模式 *.c
在当前目录中文件名以 .c 结尾的文件中递归搜索“search-pattern”。如果当前目录中没有这样的文件,它将找不到任何内容。
您的第二条命令行(再次忽略 -l 标志):
> grep -lr search-pattern *
在当前目录和所有子目录中的所有文件中递归搜索“搜索模式”(因为 * 被解释为“文件夹名称”的通配符)。
如果您从两个命令行中删除“-l”标志,则两个命令行都会“在所有 .c 文件中递归搜索模式”,第一个在当前目录中,第二个通过当前目录和所有子目录的递归下降进行搜索。
接下来的讨论假定您的意图只是对当前目录中的 .c 文件进行递归搜索(如您的第一个命令行所暗示的)。
讨论:
我倾向于将查找和列出感兴趣的文件的任务留给ls为此目的而构建的实用程序,让它每行列出一个文件名。然后我将构建命令行grep和参数(为此目的而建立的实用程序)来自ls以及你想要的图案grep寻找(因此使用grep以最自然的方式)。生成的命令如下所示:
ls -1 *.c | xargs grep "C.*t"
测试用例:
在包含以下内容的目录中:
Erlang hello.cs hello.exe somefile.c someotherfile.c
为了遵循您对意图的描述,我希望我的命令行找到文件 somefile.c 和 someotherfile.c,并在这些文件中搜索以大写 C 开头并以小写 t 结尾的模式。
文件somefile.c包括:
Ignore this!
Content
... this too ...
... and this.
文件 someotherfile.c 包括
Content to find
Ingore this
和我们的命令
ls -1 *.c | xargs grep "C.*t"
产生这样的结果:
somefile.c:Content
someotherfile.c:Content to find
向 grep 提供 -v 参数将给出相反的结果,即命令:
ls -1 *.c | xargs grep -v "C.*t"
给出结果:
somefile.c:Ignore this!
somefile.c:... this too ...
somefile.c:... and this.
someotherfile.c:Ingore this
答案4
我知道这是一个相当老的话题,但由于我有同样的问题,我想以一种更简短的形式分享我实现相同问题的首选方法。
ls | grep "file.*.c"