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

时间:2019-02-01 20:03:20

标签: linux bash shell unix xargs

我正在尝试找出返回内容与多个字符串中的任何一个匹配的所有文件名的最快方法。我正在使用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

2 个答案:

答案 0 :(得分:5)

相反,我会这样做:

printf '%s\0' *.xml | xargs -0 grep -lFf ../Identifiers.list

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

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

使用并行化(例如使用四个并行进程)可能甚至更快:

printf '%s\0' *.xml | xargs -0 -P 4 grep -lFf ../Identifiers.list

为了进一步提高速度,如果文件是ASCII,则可以使用LC_ALL=C

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

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

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

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

答案 1 :(得分:0)

把字符串转换为一个正则表达式:

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

然后是grep:

def foobar(name, value): if name == 'foo': foo = value elif name == 'bar': bar = value else: raise ValueError()