如何使用“查找”忽略某些文件名?


143

我最喜欢的BASH命令之一是:

find . -name '*.*' -exec grep 'SearchString' {} /dev/null \;

它将在当前目录及其下的所有文件的内容中搜索指定的SearchString。作为开发人员,这有时会派上用场。

由于我当前的项目以及我的代码库的结构,因此,我想通过不搜索包含“ .svn”的目录中或目录中或目录下的任何文件,或者不搜索任何文件的方式,使BASH命令更加高级。以“ .html”结尾

查找的MAN页面让我有些困惑。我尝试使用-prune,它给了我奇怪的行为。为了仅跳过.html页面(开始),我尝试了以下操作:

find . -wholename './*.html' -prune -exec grep 'SearchString' {} /dev/null \;

并没有得到我希望的行为。我想我可能会错过-prune的要点。你们能帮帮我吗?

谢谢


1
仅供参考:find不是内置的bash命令,而是一个单独的程序
WakiMiko 2012年

1
您可以使用grep -rl 'SearchString'
emanuele 2014年

@emanuele您好,欢迎来到SuperUser(和Stack Exchange网络)。我是在2 1/2年前问过这个问题的。通常,如果您想添加问题的答案,请滚动至底部并在此处回答,而不要在注释中添加答案。由于此问题已经有一个可接受的答案(带有绿色选中标记的答案),因此您的答案不太可能引起太多关注。仅供参考。
科迪S

1
嗨,这不是您问题的答案。正如您在前言中所述,它用于find在文件内部进行搜索只是一个提示。
emanuele 2014年

2
FWIW -name '*.*'不会找到所有文件:仅找到.名称中带有的文件(*.*通常使用DOS风格,而在Unix中,通常只*使用该名称)。要真正匹配它们,只需完全删除参数:find . -exec ...。或者,如果您只想将grep应用于文件(并跳过目录),请执行find . -type f -exec ...
Stefan

Answers:


197

您可以使用find的求反(!)功能不匹配具有特定名称的文件:

find . ! -name '*.html' ! -path '*.svn*' -exec grep 'SearchString' {} /dev/null \;

因此,如果名称以.html结尾或在路径中的任何位置包含.svn,则该名称将不匹配,因此该exec将不会被执行。


1
我还是应该指定-name' 在那儿的某个地方?否定之前或之后,我会这样做吗?
科迪S

您的*.*匹配目的是确保仅匹配包含的文件.吗?查找将在没有name指令的情况下匹配所有文件,因此以上内容将匹配除html和svn之外的所有内容
保罗

5
我想你想要-wholename '*.svn*'而不是-name
fuenfundachtzig 2015年

2
是的,确实如此,以便将.svn目录从搜索结果中排除。
fuenfundachtzig 2015年

1
@Noumenon ! -name '.'应该.从查找结果中排除。
保罗

11

很长一段时间以来,我都遇到过同样的问题,有几种解决方案可以适用于不同的情况:

  • ack-grep是一种“开发人员grep”,默认情况下会跳过版本控制目录和临时文件。该man页面说明了如何仅搜索特定文件类型以及如何定义自己的文件
  • grep的own --exclude--exclude-diroptions可以很容易地用于跳过文件全局单个目录(不幸的是,没有全局目录)。
  • find . \( -type d -name '.svn' -o -type f -name '*.html' \) -prune -o -print0 | xargs -0 grep ... 应该可以使用,但从长远来看,上述选择可能不太麻烦。

9

以下find命令对名称中包含 .svn的目录进行修剪,尽管它没有下降到该目录中,但已打印的修剪路径名...(-name '*.svn'是原因!)..

您可以通过以下方式过滤掉目录名称::grep -d skip静默跳过此类输入“目录名称”。

使用GNU grep,您可以使用-H代替/dev/null。作为一个小问题:\+可能比快得多\;。对于一百万个单行文件,使用\;时间为4m20s\+仅使用了1.2s

以下方法使用xargs代替-exec,并假定\n您的任何文件名中都没有换行符。这里使用xargs的与find的相同\+

xargs通过将输入分隔符更改为'\n'with -d选项,可以传递包含连续空格的文件名。

这不包括名称包含 .svn且仅包含不以结尾的文件的目录.html

find . \( -name '*.svn*' -prune  -o ! -name '*.html' \) |
   xargs -d '\n' grep -Hd skip 'SearchString'

1
感谢您指出\+-exec操作的变体。万岁出现了轻微的附带问题!
克里斯蒂安·朗

当然,由于+不是shell的特殊字符,因此无需\在其之前键入。
斯科特,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.