unixfind(1)实用程序非常有用,它允许我对符合特定规范的许多文件执行操作,例如
find /dump -type f -name '*.xml' -exec java -jar ProcessFile.jar {} \;
Run Code Online (Sandbox Code Playgroud)
上面的代码可能会对特定目录中的每个 XML 文件运行脚本或工具。
假设我的脚本/程序占用了大量 CPU 时间并且我有 8 个处理器。一次处理最多 8 个文件会很好。
GNU make 允许使用-j标志进行并行作业处理,但find似乎没有这样的功能。是否有替代的通用作业调度方法来解决这个问题?
Gai*_*ius 74
xargs带有-P选项(进程数)。假设我想压缩 4-cpu 机器上目录中的所有日志文件:
find . -name '*.log' -mtime +3 -print0 | xargs -0 -P 4 bzip2
Run Code Online (Sandbox Code Playgroud)
您还可以说-n <number>每个进程的最大工作单元数。所以说我有 2500 个文件,我说:
find . -name '*.log' -mtime +3 -print0 | xargs -0 -n 500 -P 4 bzip2
Run Code Online (Sandbox Code Playgroud)
这将启动 4 个bzip2进程,每个进程有 500 个文件,然后当第一个进程完成时,将启动最后 500 个文件的另一个进程。
不知道为什么前面的答案使用xargs and make,那里有两个并行引擎!
eph*_*ent 45
GNU 并行也可以提供帮助。
find /dump -type f -name '*.xml' | parallel -j8 java -jar ProcessFile.jar {}
Run Code Online (Sandbox Code Playgroud)
请注意,如果没有-j8参数,则parallel默认为您机器上的内核数:-)
无需“修复” find——利用make自身来处理并行性。
让您的进程创建一个日志文件或其他一些输出文件,然后使用像这样的 Makefile:
.SUFFIXES: .xml .out
.xml.out:
java -jar ProcessFile.jar $< 1> $@
Run Code Online (Sandbox Code Playgroud)
并因此调用:
find /dump -type f -name '*.xml' | sed -e 's/\.xml$/.out/' | xargs make -j8
Run Code Online (Sandbox Code Playgroud)
更好的是,如果您确保仅在 Java 进程成功完成后才创建输出文件,您可以利用make的依赖处理来确保下次只完成未处理的文件。
小智 5
Find 有一个并行选项,您可以直接使用“+”符号来使用;不需要 xargs。将它与 grep 结合起来,它可以快速地遍历你的树来寻找匹配项。例如,如果我正在查找源目录中包含字符串“foo”的所有文件,我可以调用
find sources -type f -exec grep -H foo {} +