列出其内容可以与多个字符串中的任何一个匹配的所有文件名的最快方法

Fastest way to list all the file names whose content can match with any of multiple strings

我正在尝试找出 return 其内容与多个字符串中的任何一个匹配的所有文件名的最快方法。我正在使用 xargs 进行迭代。


$ cat ../Identifiers.list | xargs -i grep -l "{}" .

打印所有文件名大约需要 8 分钟。有没有更快的方法?


Identifiers.list - 文件内容如下

287434
383460
633491
717255
827734
253735
635373
553888
910366

目录中的文件数 - 36000

$ ls -l *.xml | wc -l
36000

我会反过来做:

printf '%s[=10=]' *.xml | xargs -0 grep -lFf ../Identifiers.list

这将只检查每个文件一次,并在找到匹配项后立即停止。 -F 使用固定字符串匹配而不是正则表达式,这应该会进一步加快速度。

我认为您的方法隐含地使用了 -L 1(因为 -i),因此对于 Identifier.list 的每一行,它遍历所有文件。

并行化可能会更快,例如使用四个并行进程:

printf '%s[=11=]' *.xml | xargs -0 -P 4 grep -lFf ../Identifiers.list

如果您的文件是 ASCII 文件,为了进一步加快速度,您可以使用 LC_ALL=C:

printf '%s[=12=]' *.xml | LC_ALL=C xargs -0 -P 4 grep -lFf ../Identifiers.list

使用 xargs 是一个好主意,即使没有并行化:直接使用 grep,如

grep -lFf ../Identifiers.list *.xml

可能会引发错误,因为 *.xml 扩展到太长的命令行。

将字符串放入一个正则表达式中:

(?:287434|383460|633491|717255|827734|253735|635373|553888|910366)

然后 grep:

grep -P '(?:287434|383460|633491|717255|827734|253735|635373|553888|910366)' *