11

grep 可以使用该-r选项进行递归搜索。但是,我想知道 grep 是否能够递归地搜索指定数量的子文件夹级别的查询字符串。例如,我有一个文件夹root,其中包含文件夹parent1, parent2, ..., parentN。每个父文件夹都有普通的文本文件和名为child1, child2, ..., childM. 我想从根级别运行 grep 并在父母内部的文件中搜索而不查看子文件夹。有没有一种简单的方法可以做到这一点?

4

2 回答 2

18

正如肯特 所说,你不能用顺子做到这一点grep;它根本不够强大。诀窍是用来find确定要搜索的文件,并将find生成的文件列表传递给grep.

如果你运行man find,你会得到一个包含许多选项的手册页find。我们在这里感兴趣的是-maxdepth.

让我们建立我们需要的命令。在每个阶段运行命令以查看它的外观:

  • find .将列出当前文件夹 ( .) 或任何后代文件夹中存在的所有文件和文件夹。

  • find . -maxdepth 1将列出当前文件夹中的所有文件和文件夹。find . -maxdepth 2同样会列出当前文件夹中的所有文件和文件夹以及任何直接子文件夹。等等……</p>

  • 请注意,我们也列出了文件夹;我们不希望这样,因为grep无法搜索文件夹本身,只能搜索文件夹中的文件。添加-type f以仅获取列出的文件:find . -maxdepth 2 -type f.

现在我们知道了要搜索的文件,我们需要grep搜索这些文件。执行此操作的标准方法是使用xargs

find . -maxdepth 2 -type f | xargs grep <text-to-search-for>

从(即您通常在屏幕上看到的内容)获取“标准输出”,又名“stdout”,并将其通过管道传输到的|“标准输入”,即“stdin”,即,如果您在运行时键入通常会发生什么程序。findxarg

xargs是一个狡猾的小程序grep <text-to-search-for>,在添加它在标准输入上收到的所有参数之后,它运行你告诉它的任何东西(这里,)。结果是grep它将搜索找到的每个文件find

但是,如果您的某些文件名中有空格,这将不起作用,因为xargs认为空格分隔两个不同的文件名,而不是一个文件名的一部分。有很多方法可以处理这个问题(理想的方法是不要在文件名中使用空格),最常见的方法是使用find.

如果您向 中添加-exec参数find,它将执行您指定的所有内容,直到 a;+。如果您添加一个{}(即文字字符{}),它将用所有文件的列表替换它。由于find这样做,它知道文件名中的空格应该在文件名中。

因此,做你想做的事情的最好方法是:

find . -type f -maxdepth 2 -exec grep <text-to-search-for> {} +

(The difference between ending with + and ; makes no difference here. If you're interested it's in man find, but the short version is that + is faster but means you can only have one {} in the command.)

于 2013-03-04T15:42:16.300 回答
7

你可以试试这些:

grep

 --exclude=GLOB
              Skip files whose base name matches GLOB  (using
              wildcard  matching).   A file-name  glob  can  use *,
              ?, and [...]  as wildcards, and \ to quote a wildcard
              or backslash character literally.

       --exclude-from=FILE
              Skip files whose base name matches any of the file-name
              globs  read  from FILE (using wildcard matching as
              described under --exclude).

       --exclude-dir=DIR
              Exclude directories matching the pattern DIR from
              recursive searches.

或使用这个find | xargs grep

使用 find,您可以定义级别

编辑

一个命令到另一个命令的管道输出在 linux/unix 世界中非常常见。我敢打赌你每天都这样做。

echo "abc"|sed 's/a/x/'
find . -name "*.pyc" |xargs rm
awk 'blahblah' file | sort |head -n2 
tree|grep 'foo'
mvn compile|ack 'error'
...

请注意,并非上述所有示例都是有效的。它们只是例子。

于 2013-03-01T22:30:55.547 回答