如何将 grep 限制为仅搜索特定的文件?

4
我们有一个相当庞大而复杂的文件系统,我正在尝试生成包含特定文本字符串的文件列表。这应该很简单,但我需要排除"./svn"和"./pdv"目录(以及可能的其他目录),并且只查看*.p、*.w或.i类型的文件。
我可以用程序轻松完成这个任务,但运行速度非常慢。我想加快这个过程(以便不重复搜索数千个文件),因为我需要根据长列表运行此类搜索条件。
通常,我们使用以下方式搜索文件系统:
find . -name "*.[!r]*" -exec grep -i -l "search for me" {} \;

这个是可行的,但我随后必须使用一个程序来排除不需要的目录,所以它运行得非常缓慢。
在查看这里的主题之后: Stack Overflow thread 我决定尝试一些其他的方法:
grep -ilR "search for me" . --exclude ".svn" --excluse "pdv" --exclude "!.{p,w,i*}" 

排除 './svn' 目录,但不排除 './pdv' 目录,不限制查看的文件。

grep -ilR "search for me" . --exclude ".svn" --excluse "pdv" --include "*.p" 

排除 './svn' 目录,但不排除 './pdv' 目录,不限制所查看的文件。
find . -name "*.[!r]*" -exec grep -i -l ".svn" | grep -i -l "search for me" {} \;

我甚至无法成功运行这个程序(或它的变种)。

find . ! -name "*.svn*" -prune -print -exec grep -i -l "search for me" {} \;

没有返回任何内容。看起来它会在找到 .svn 目录后停止。


明确地说,我正在寻找与“*.p”、“*.w”或“*.i*”中任何一个匹配的所有文件,并排除名为“.svn”和“pdv”的目录。非常感谢。 - Colin
2
在你的例子中,--excluse "pdv"(注意拼写错误s/d)在两种情况下都存在,你抱怨这个特定条件不起作用...只是检查一下,拼写错误不是主要问题。 - geronime
1
嗯,我认为“D'Oh!”是一个不错的开始。感谢你发现了这个问题。 - Colin
@geronime,我刚刚尝试了一下修正了拼写错误的示例(希望如此)。搜索字符串是 grep -ilR "run" . --exclude ".svn" --exclude "pdv" --exclude "!.{p,w,i*}"。不幸的是,由于结果集现在包括 .svn/text-base/jr83144.p.svn-basepdv/cm/backupds.i,我认为这并没有起作用。非常感谢。 - Colin
你是否尝试过使用 --exclude-dir 参数?我认为这实际上就是问题所在。请参考 grep 的手册。 - geronime
显示剩余4条评论
4个回答

2
如何尝试以下内容:

类似于这样的东西:

find . \( \( -name .svn -o -name pdv \) -type d -prune \) -o \( -name '*.[pwi]' -type f -exec grep -i -l "search for me" {} + \)

这将会:
- 忽略名为 .svn 和 pdv 的目录的内容
- 搜索文件(和指向文件的符号链接)命名为 *.[pwi]

exec 后面的 + 选项表示将尽可能多的文件收集到一个命令中,以适应命令行的长度限制(在Linux中大约是100万个字符)。如果你需要迭代处理数千个文件,则可以大大加快处理速度。

2
以下命令查找只包含require 'bundler/setup'行的*.rb文件,并在搜索.git.bundle目录时排除。我认为这是相同的用例。
grep -ril --exclude-dir .git --exclude-dir .bundle \
  --include \*.rb "^require 'bundler/setup'$" .

问题出在交换了--exclude--exclude-dir参数上。请参考grep(1)手册。
另外,请注意排除/包含参数仅接受GLOB,不接受正则表达式,因此单字符后缀范围可以通过一个--include参数完成,但更复杂的条件需要更多的参数。
--include \*.[pwi] --include \*.multichar_sfx ...

0
你可以尝试以下方法:
find path_starting_point -type f | grep regex_to_filter_file_names | xargs grep regex_to_find_inside_matched_files

我已经尝试过这个方法,但是无法使 "regex_to_filter_file_names" 正常工作。我尝试了 find . -type f | grep .*\.p | xargs -il grep "run",但它返回的文件不仅包括以 .p 结尾的文件,还包括以 .ixx 结尾的文件。 - Colin
也许使用 grep '\.\[pwi\]$' 来匹配以".p", ".w" 或 ".i" 后缀结尾的文件。 - geronime

0
find . -name "filename_regex"|grep -v '.svn' -v '.pdv'|xargs grep -i 'your search string'

我也尝试过这个,但是正则表达式仍然无法工作。只使用一个简单的示例 find . -name ".*\.i" 测试这个概念并没有返回任何值。 - Colin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接