2012-03-05 23:28:16 +0000 2012-03-05 23:28:16 +0000
148
148

如何使用 "查找 "来忽略某些文件名?

我最喜欢的一个BASH命令是

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

这条命令可以搜索当前目录下所有文件的内容,寻找指定的SearchString. 作为一个开发者,这个功能有时会很方便。

由于我目前的项目和我的代码库结构,我想让这个BASH命令更加高级,不搜索包含".svn “的目录下的任何文件,或者以”.html “结尾的任何文件

不过查找的MAN页面让我很困惑。我试着使用-prune,但它给了我奇怪的行为。为了只跳过.html页面(开始),我尝试了:

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

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

谢谢

答案 (3)

209
209
209
2012-03-06 00:40:37 +0000

你可以使用find的否定(!)功能来不匹配具有特定名称的文件:

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

所以如果名称以.html结尾或者路径中的任何地方包含.svn,它将不匹配,因此exec将不会被执行。

12
12
12
2012-03-06 13:54:15 +0000

我遇到同样的问题已经很久了,有几种解决方法,可以适用于不同的情况。

  • ack-grep是一种 “开发者的grep",默认情况下会跳过版本控制目录和临时文件。man页面解释了如何只搜索特定的文件类型以及如何 定义你自己的
  • grep自己的--exclude--exclude-dir选项可以很容易地用来跳过文件globs和_单个目录(不幸的是,没有针对目录的globbing)。
  • find . \( -type d -name '.svn' -o -type f -name '*.html' \) -prune -o -print0 | xargs -0 grep ...应该可以用,但从长远来看,上述选项可能不太麻烦。
9
9
9
2012-03-06 03:29:21 +0000

下面的find命令会修剪那些名字中包含.svn的目录,虽然它不会进入目录,但修剪后的路径名会被打印出来……(-name '*.svn'是原因!) …

你可以通过。

你可以通过:grep -d skip过滤掉这些目录名,它将默默地跳过这些输入的 “目录名"。

使用GNU grep,你可以用-H代替/dev/null。作为一个小问题:可以比`\;`快得多,例如:对于100万个单行文件,使用`\;`需要_4m20s_,使用只需要1.2s

下面的方法使用xargs代替-exec,并假设你的文件**名中都没有新行\n。在这里,xargs与find的``大同小异。

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

这排除了名字中包含.svn的目录,只gps不以.html结尾的文件。

find . \( -name '*.svn*' -prune -o ! -name '*.html' \) |
   xargs -d '\n' grep -Hd skip 'SearchString'
``` 这不包括名字中包含0x6&的目录,只搜索不以0x6&结尾的文件。