unix find(1)
实用程序是非常有用的,允许我对许多匹配某些规范的文件执行操作,例如
find /dump -type f -name '*.xml' -exec java -jar ProcessFile.jar {} \;
以上可能会在特定目录中的每个XML文件上运行脚本或工具。
假设我的脚本/程序需要很多CPU时间,而且我有8个处理器。 一次处理多达8个文件将是很好的。
GNU make允许使用-j
标志进行并行作业处理,但find
似乎没有这种function。 有没有一个替代的通用工作调度方法来解决这个问题?
xargs
与-P
选项(进程数)。 假设我想压缩4-cpu机器目录中的所有日志文件:
find . -name '*.log' -mtime +3 -print0 | xargs -0 -P 4 bzip2
你也可以用-n <number>
来表示每个进程的最大工作单元数。 所以说我有2500个文件,我说:
find . -name '*.log' -mtime +3 -print0 | xargs -0 -n 500 -P 4 bzip2
这会启动4个bzip2
进程,每个进程有500个文件,然后当第一个完成时,会启动最后的500个文件。
不知道为什么以前的答案使用xargs
和 make
,你有两个并行引擎!
GNU并行也可以提供帮助。
find /dump -type f -name '*.xml' | parallel -j8 java -jar ProcessFile.jar {}
请注意,如果没有-j8
参数,则parallel
默认为您计算机上的核心数量:-)
无需“修复” find
– 利用自己来处理并行性。
让你的进程创build一个日志文件或其他输出文件,然后使用如下的Makefile:
.SUFFIXES: .xml .out .xml.out: java -jar ProcessFile.jar $< 1> $@
并由此调用:
find /dump -type f -name '*.xml' | sed -e 's/\.xml$/.out/' | xargs make -j8
更好的是,如果确保在成功完成Java进程时才创build输出文件,则可以利用make
的依赖性处理来确保下一次只有未处理的文件完成。
Find有一个可以直接使用“+”符号的并行选项; 不需要xargs。 把它和grep结合起来,就可以快速的通过你的树来寻找火柴。 例如,如果我正在寻找包含string“foo”的源代码目录中的所有文件,我可以调用
find sources -type f -exec grep -H foo {} +