А лучше юникс найти с параллельной обработкой?


43

find(1)Утилита unix очень полезна, позволяя мне выполнять действия со многими файлами, которые соответствуют определенным спецификациям, например

find /dump -type f -name '*.xml' -exec java -jar ProcessFile.jar {} \;

Вышеприведенное может запускать скрипт или инструмент для каждого файла XML в определенном каталоге.

Допустим, мой скрипт / программа занимает много процессорного времени, а у меня 8 процессоров. Было бы неплохо обрабатывать до 8 файлов одновременно.

GNU make допускает параллельную обработку заданий с -jфлагом, но find, похоже, не обладает такой функциональностью. Есть ли альтернативный общий метод планирования работы, чтобы приблизиться к этому?

Ответы:


65

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 вас есть два параллельных движка!


7
При использовании find / xargs будьте осторожны: по умолчанию находите переводы строк как разделители вывода, а по умолчанию xargs - любые пробелы в качестве разделителей ввода. Используйте -0 в обоих случаях, чтобы быть безопасным, или переключитесь на параллельную GNU, которая по умолчанию переводится на новые строки в качестве разделителей ввода (соответствует выводу find).
Эфимент

1
Ух ты, потрясающе! Я только что проверил, и это правда, у xargs есть -Pопция!
пп.

Остерегайтесь использования xargs -P- у него есть постоянная ошибка с искажением вывода (в отличие от parallel) всякий раз, когда 2 потока производят вывод в один и тот же момент ...
Влад,

34

Параллельно GNU тоже может помочь.

find /dump -type f -name '*.xml' | parallel -j8 java -jar ProcessFile.jar {}

Обратите внимание, что без -j8аргумента по parallelумолчанию используется количество ядер на вашем компьютере :-)


6

Не нужно «исправлять» 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обработкой зависимостей, чтобы в следующий раз были выполнены только необработанные файлы.


1
Надеемся, что в этих именах нет пробелов или других «интересных» символов; Make не справляется с этим очень элегантно.
Эфимент

Отличная идея! Никогда не думал об использовании make-файлов, как это.
oscfri

3

Find имеет параллельную опцию, которую вы можете использовать напрямую, используя символ «+»; не требуется xargs. Комбинируя его с grep, он может быстро копаться в вашем дереве в поисках спичек. например, если я ищу все файлы в моем каталоге исходников, содержащие строку 'foo', я могу вызвать
find sources -type f -exec grep -H foo {} +


12
Читая руководство по поиску, вы можете увидеть, что -exec command +синтаксис не запускает его параллельно, а «группирует» много файлов вместе и запускает команду с несколькими файлами в качестве аргументов одновременно. Бывает, что grep может параллельно просматривать цели.
Gyscos
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.