xargs
широко используется в сценариях оболочки; обычно легко переделать это использование в использовании удара while read -r; do ... done
или while read -ar; do ... done
циклы.
Когда должен xargs
будьте предпочтены, и когда должен, в то время как - считал циклы быть предпочтенным?
Особенность циклов while
заключается в том, что они обычно обрабатывают один элемент за раз, часто когда это не нужно. Здесь xargs
имеет преимущество - он может группировать аргументы, чтобы одна команда могла обрабатывать множество элементов.
Например, цикл while:
pax> echo '1
2
3
4
5' | while read -r; do echo $REPLY; done
1
2
3
4
5
и соответствующий xargs
:
pax> echo '1
2
3
4
5' | xargs echo
1 2 3 4 5
Здесь вы можете видеть, что строки обрабатываются одна за другой с помощью while
и вместе с xargs
. Другими словами, первое эквивалентно echo 1; эхо 2; эхо 3; эхо 4; echo 5
, тогда как последний эквивалентен echo 1 2 3 4 5
(пять процессов вместо одного). Это действительно имеет значение при обработке тысяч или десятков тысяч строк, поскольку создание процесса требует времени.
Это наиболее выгодно при использовании команд, которые могут принимать несколько аргументов, поскольку это уменьшает количество запускаемых отдельных процессов, что значительно ускоряет работу.
Когда я обрабатываю небольшие файлы или команды, запускаемые для каждого элемента, сложны (когда мне лень писать отдельный скрипт для xargs
), я буду использовать ], а вариант
.
Если меня интересует производительность (большие файлы), я буду использовать xargs
, даже если мне придется писать отдельный сценарий.
Некоторые реализации xargs
также понимают аргумент -P MAX-PROCS
, который позволяет xargs
запускать несколько заданий параллельно. Это было бы довольно сложно смоделировать с помощью цикла при чтении
.
"xargs" имеет параметр "-n max-args", который, я думаю, позволит вызывать команду для нескольких аргументов одновременно (полезно для "grep", "rm" и многих других подобных программ) {{1} } Попробуйте пример из man-страницы:
cut -d: -f1 < /etc/passwd | sort | xargs -n 5 echo
И вы увидите, что он "echo" -ed 5 пользователей в строке
PS И не забывайте, что «xargs» - это программа (вроде подоболочки). Таким образом, нет способа получить информацию для вашего shell-скрипта простым способом (вам нужно будет прочитать вывод ваших "xargs" и каким-то образом интерпретировать, чтобы заполнить ваши переменные оболочки / env).
GNU Parallel http://www.gnu.org/software/parallel/ имеет преимущества от xargs
(используя -m) и преимущества while-read
с новой строкой в качестве разделителя и некоторые новые возможности (например, группировка вывода, параллельное выполнение заданий на удаленных компьютерах и контекстная замена).
Если у вас установлен GNU Parallel, я не вижу ни одной ситуации, в которой вы могли бы использовать xargs
. И единственная ситуация, в которой я бы использовал read-while
- это если блок для выполнения настолько велик, что его невозможно уместить в одну строку (например, если он содержит if-заявления или что-то подобное), и вы отказываетесь делать функцию bash.
Для всех небольших сценариев я нахожу более читаемым использование GNU Parallel. Пример paxdiablo:
echo '1
2
3
4
5' | parallel -m echo
Преобразование WAV-файлов в MP3 с помощью GNU Parallel:
find sounddir -type f -name '*.wav' | parallel -j+0 lame {} -o {.}.mp3
Посмотрите вступительное видео по GNU Parallel: http://www.youtube.com/watch?v=OpaiGYxkSuQ