С чего начать Первые шаги трек · 15 ступеней
Linux Labs

xargs — построение аргументов из потока

3 мин GNU findutils

Превращает строки stdin в аргументы команды; без -0 имена файлов с пробелами и переводами строк ломают разбор.

Шпаргалка

5 команд Версия для печати
  • find . -name '*.x' -print0 | xargs -0 rm безопасно (пробелы)
  • ... | xargs -I{} cp {} /dst/ подстановка {}
  • ... | xargs -P4 -n1 cmd параллельно
  • ... | xargs -rt cmd не на пустом + показать
  • ... | xargs -n1 по одному аргументу

Обзор

xargs берёт строки со stdin и подставляет их как аргументы команды. Нужен, когда команда не читает stdin, а ждёт аргументы (как rm, chmod).

bash
echo "a b c" | xargs touch        # создаст файлы a, b, c
find . -name '*.tmp' | xargs rm   # удалить найденное

Ключи

7

Без -0 xargs разбивает вход по пробелам и переводам строк — имя файла с пробелом превратится в два отдельных аргумента. Безопасный путь — разделитель NUL на обеих сторонах конвейера: find -print0 (или grep -Z) вместе с xargs -0. -I {} неявно ограничивает вызов одним аргументом за раз, как -n1, потому что подставить сразу несколько значений в одно место нельзя.

bash
... | xargs -n1 cmd               # по одному аргументу за вызов
... | xargs -I{} cp {} /backup/   # подстановка {} (часто -I подразумевает -n1)
... | xargs -P4 -n1 cmd           # параллельно в 4 процесса
cat urls.txt | xargs -P8 -I{} curl -sO {}   # качать 8 в параллель
... | xargs -rt cmd               # не на пустом + показать команду
Ключ Что делает Пример
-0 Вход разделён символом NUL — безопасно для имён с пробелами (пара к find -print0). find . -name '*.log' -print0 | xargs -0 rm
-n N Передавать не более N аргументов за один вызов команды. ... | xargs -n1 cmd
-I {} Подставить аргумент в произвольное место команды, по одному за вызов. ... | xargs -I{} cp {} /backup/
-r --no-run-if-empty Не запускать команду вовсе, если на входе нет аргументов. ... | xargs -r cmd
-P N Запускать до N процессов параллельно. cat urls.txt | xargs -P8 -I{} curl -sO {}
-t Печатать собранную команду перед запуском — удобно для отладки. ... | xargs -t cmd
-a FILE Читать аргументы из файла, а не из stdin. xargs -a urls.txt wget

Ничего не найдено. Попробуй запрос короче.

Рецепты

1

Безопасно с именами файлов

Пробелы и переводы строк в именах ломают наивный xargs. Правильно — через нулевой разделитель:

bash
find . -name '*.log' -print0 | xargs -0 rm        # -print0 + -0
grep -rlZ "TODO" . | xargs -0 sed -i 's/TODO/DONE/g'   # -Z у grep + -0 у xargs

Неполадки

5

Имена с пробелами разрезаются

find ... -print0 | xargs -0 (или find -exec cmd {} +, см. find).

xargs запустился на пустом вводе и наделал бед

Добавь -r (--no-run-if-empty) — не запускать команду без аргументов.

«Argument list too long» / один вызов с тьмой аргументов

xargs сам бьёт на партии (лимит системы); для контроля — -n N. Альтернатива — find -exec cmd {} + (тоже группирует).

Нужно вставить аргумент не в конец

xargs -I{} cmd ... {} ... — {} подставится в указанное место (по одному вызову).

Параллельный вывод перемешивается

При -P строки разных процессов чередуются. Логируй в отдельные файлы или используй GNU parallel (он умеет упорядочивать вывод).

См. также

  • find — Поиск файлов по имени, размеру, времени, правам; действия над найденным.
  • grep — Поиск строк по шаблону; регулярки, рекурсия, контекст.
  • files-basics — Навигация и файлы — ls, cd, cp, mv, rm, cat, less, head, tail, копипаст в терминале.
Загрузка…