Unix find(1)
Утилита очень полезна, позволяя мне выполнять действия со многими файлами, соответствующими определенным спецификациям, например
find /dump -type f -name '*.xml' -exec java -jar ProcessFile.jar {} \;
Вышеупомянутое может запускать сценарий или инструмент для каждого XML-файла в определенном каталоге.
Допустим, мой сценарий / программа занимает много процессорного времени, а у меня 8 процессоров. Было бы неплохо обрабатывать до 8 файлов за раз.
GNU make позволяет выполнять параллельную обработку заданий с помощью -j
флаг, но find
похоже, не имеет такой функции. Есть ли альтернативный общий метод планирования заданий для достижения этой цели?
xargs
с -P
вариант (количество процессов). Скажем, я хотел сжать все файлы журналов в каталоге на машине с 4 процессорами:
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 parallel тоже может помочь.
find /dump -type f -name '*.xml' | parallel -j8 java -jar ProcessFile.jar {}
Обратите внимание, что без -j8
аргумент parallel
по умолчанию количество ядер на вашем компьютере :-)
Не нужно «исправлять» find
- использовать make
сам обрабатывать параллелизм.
Попросите ваш процесс создать файл журнала или какой-либо другой выходной файл, а затем использовать 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, вы можете воспользоваться make
обработка зависимостей, чтобы гарантировать, что в следующий раз будут обработаны только необработанные файлы.
У Find есть опция параллельности, которую можно использовать напрямую, используя символ «+»; xargs не требуется. Комбинируя его с grep, он может быстро разорвать ваше дерево в поисках совпадений. например, если я ищу все файлы в моем каталоге источников, содержащие строку 'foo', я могу вызвать
find sources -type f -exec grep -H foo {} +