Grep 在几千个文件中

Grep 在几千个文件中

我的目录中有 cca​​ 26 000 个文件,我需要 grep 所有这些文件。问题是,我需要尽快得到它,所以制作 grep 从 find 命令中获取一个文件的名称并将匹配项写入文件的脚本并不理想。在出现“参数列表太长”问题之前,花费了 cca 2 分钟的时间来 grep 所有这些文件。有什么想法如何去做吗?编辑:有一个脚本一直在创建新文件,因此不可能将所有文件放入不同的目录。

答案1

find

cd /the/dir
find . -type f -exec grep pattern {} +

(-type f是只搜索常规的文件(也不包括符号链接,即使它们指向常规文件)。如果您想搜索除目录之外的任何类型的文件(但要注意某些类型的文件,如 fifos 或 /dev/zero,您通常不想读取),请替换-type f为 GNU 特定的文件! -xtype d-xtype d匹配以下文件)类型目录符号链接解析后))。

使用 GNU grep

grep -r pattern /the/dir

(但请注意,除非您有最新版本的 GNU grep,否则在进入目录时将遵循符号链接)。除非您添加选项,否则不会搜索非常规文件-D read。不过,最新版本的 GNUgrep仍然不会在符号链接内搜索。

非常旧的 GNU 版本find不支持标准{} +语法,但您可以使用非标准语法:

cd /the/dir &&
  find . -type f -print0 | xargs -r0 grep pattern

性能可能受 I/O 限制。也就是说,进行搜索的时间就是从存储中读取所有数据所需的时间。

如果数据位于冗余磁盘阵列上,一次读取多个文件可能会提高性能(否则可能会降低性能)。如果性能不受 I/O 限制(因为例如所有数据都在缓存中),并且您有多个 CPU,那么并发greps也可能有所帮助。您可以使用 GNUxargs-P选项来做到这一点。

例如,如果数据位于具有 3 个驱动器的 RAID1 阵列上,或者如果数据位于缓存中并且您有 3 个空闲时间的 CPU:

cd /the/dir &&
  find . -type f -print0 | xargs -n1000 -r0P3 grep pattern

(此处用于每 1000 个文件-n1000生成一个新grep文件,一次最多并行运行 3 个文件)。

但请注意,如果 的输出grep被重定向,您最终会得到 3 个grep进程的严重交错输出,在这种情况下,您可能希望将其运行为:

find . -type f -print0 | stdbuf -oL xargs -n1000 -r0P3 grep pattern

(在最近的 GNU 或 FreeBSD 系统上)或使用--line-bufferedGNU 选项grep

如果pattern是固定字符串,添加该-F选项可以改善问题。

如果不是多字节字符数据,或者为了匹配该模式,数据是否为多字节字符并不重要,则:

cd /the/dir &&
  LC_ALL=C grep -r pattern .

可以显着提高性能。

如果您最终经常进行此类搜索,那么您可能需要使用众多搜索引擎之一来索引您的数据。

答案2

对于大多数文件系统来说,单个目录中的 26000 个文件已经很多了。阅读这个大目录可能会花费很大一部分时间。考虑将其拆分为较小的目录,每个目录仅包含数百个文件。

find除非你做错了,否则打电话并不能解释糟糕的表现。这是一种遍历目录的快速方法,并确保您不会冒险尝试执行太长的命令行。确保使用-exec grep PATTERN {} +,它会在每次命令调用时打包尽可能多的文件,而不是-exec grep PATTERN {} \;,它对grep每个文件执行一次:每个文件执行一次命令可能会明显变慢。

答案3

如果您需要多次 grep 所有文件(正如您所说,运行脚本),我建议您查看 ram 磁盘,将所有文件复制到那里,然后多次 grep 文件,这将加快您的搜索速度至少 100 倍。

你只需要足够的内存。否则,您应该考虑对文件进行索引,例如。进入 lucene 或 nosql 数据库,然后对其运行查询。

答案4

目录下的所有文件

grep 'search string' *

递归地

grep -R 'search string' *

相关内容