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

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


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

由于我当前的项目以及我的代码库的结构,我想通过不搜索包含“ “ .svn”或任何以“ .html”结尾的文件。我尝试使用-prune,它给了我奇怪的行为。为了仅跳过.html页(开始),我尝试了:

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


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

谢谢

评论

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

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

嗨,这不是您问题的答案。正如您在序言中所述,使用find在文件内部搜索一样,这只是一个提示。

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

#1 楼

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

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


因此,如果名称以.html结尾或在。路径,它将不匹配,因此将不会执行exec。

评论


我还是应该指定-name'。那里的某个地方?否定之前或之后,我会这样做吗?

– Cody S
2012年6月6日,下午1:21

您是否希望*。*匹配以确保仅匹配包含。?的文件?查找将在没有名称指令的情况下匹配所有文件,因此以上内容将匹配除html和svn之外的所有文件

– Paul
2012年6月6日在1:23



我认为您想要-wholename'* .svn *'而不是-name。

– fuenfundachtzig
2015年5月9日22:35

是的,确实如此,因此.svn目录从搜索结果中排除。

– fuenfundachtzig
2015年5月10日在12:41

@Noumenon! -名称 '。'应该排除。从查找结果。

– Paul
16-10-24在2:57

#2 楼

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



ack-grep是一种“开发人员的grep”默认情况下会跳过版本控制目录和临时文件。 man页面说明了如何仅搜索特定文件类型以及如何定义自己的文件。目录,很遗憾)。

grep应该可以工作,但从长远来看,上述选择可能不太麻烦。


#3 楼

以下find命令对名称包含.svn的目录进行修剪,尽管它不属于该目录,但会打印修剪的路径名...(-name '*.svn'是原因!)..

您可以过滤通过以下命令删除目录名称:grep -d skip,它会静默跳过此类输入“目录名称”。

通过GNU grep,您可以使用-H而不是/dev/null
作为一个小问题:\+可能比\;快得多。对于一百万个单行文件,使用\;花费了4m20s,使用\+花费了1.2s。

以下方法使用xargs而不是-exec,并且假设您的任何人都没有换行\n文件名。如此处所用,xargs与find的\+几乎相同。

xargs可以通过使用'\n'选项将输入定界符更改为-d来传递包含连续空格的文件名。

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

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


评论


感谢您指出-exec操作的\ +变体。万岁出现了轻微的附带问题!

–克里斯蒂安·朗(Christian Long)
2014年9月12日18:10

当然,由于+不是shell的特殊字符,因此不需要在其前面键入\。

–斯科特
16-8-28在0:35



#4 楼

本示例从搜索中排除名称中带有“ test”的文件。搜索本身仅查找XML文件的“ ProductReplacement”。

find . ! -name '*test*.*' -name '*.xml' -exec grep -i 'ProductReplacement' {} \; -print


您可以使用其他



指定更多排除模式。 ! -name'file_pattern'
条目。