Gymterview
middle

Как использовать xargs?

xargs — команда, которая читает данные из stdin и передаёт их как аргументы другой команде. Это мост между выводом одной команды (через пайп) и аргументами командной строки другой.

Аналогия: если пайп | — это конвейерная лента, подающая данные на вход, то xargs — это работник, который снимает предметы с ленты и вкладывает их в руки следующему работнику (команде), который не умеет брать предметы с ленты сам.

Зачем нужен xargs

Многие команды (rm, chmod, mv, cp) принимают аргументы командной строки, но не читают stdin. Пайп | передаёт данные в stdin, а xargs конвертирует stdin в аргументы:

Пример
# Не работает — rm не читает stdin
find . -name "*.tmp" | rm

# Работает — xargs передаёт имена файлов как аргументы rm
find . -name "*.tmp" | xargs rm

Основные флаги

Пример
# -I {} — подстановка (плейсхолдер для каждого элемента)
find . -name "*.java" | xargs -I {} cp {} backup/

# -n N — передавать по N аргументов за раз
echo "a b c d e" | xargs -n 2 echo
# a b
# c d
# e

# -d — указать разделитель
echo "a:b:c" | xargs -d ':' echo
# a b c

# -0 — разделитель NUL (для файлов с пробелами/спецсимволами в именах)
find . -name "*.log" -print0 | xargs -0 rm

# -p — запрашивать подтверждение перед выполнением
find . -name "*.tmp" | xargs -p rm

# -t — показывать выполняемую команду перед выполнением
echo "file1 file2" | xargs -t rm

Параллельное выполнение

Пример
# -P N — запускать N процессов параллельно
find . -name "*.png" | xargs -P 4 -I {} convert {} -resize 50% small_{}

Практические примеры

Пример
# Удалить все .class файлы
find . -name "*.class" -print0 | xargs -0 rm -f

# Найти строку во всех Java-файлах
find src -name "*.java" | xargs grep -l "deprecated"

# Массовое создание бэкапов
ls *.conf | xargs -I {} cp {} {}.bak

# Убить все Java-процессы
pgrep java | xargs kill

# Сжать каждый лог-файл отдельно
find /var/log -name "*.log" -mtime +7 | xargs -I {} gzip {}

# Подсчитать строки кода в проекте
find src -name "*.java" | xargs wc -l

# Массовая замена текста в файлах
find . -name "*.yml" | xargs sed -i 's/localhost/0.0.0.0/g'

xargs vs find -exec

Характеристика find ... -exec cmd {} \; find ... | xargs cmd
Запуск процессов Один процесс на файл Один процесс на пачку файлов
Производительность Медленнее Быстрее
Пробелы в именах Безопасно Нужен -print0 | xargs -0
Пакетная обработка -exec cmd {} + По умолчанию

Совет: для безопасной работы с именами файлов, содержащими пробелы и спецсимволы, всегда используйте find ... -print0 | xargs -0.

На собеседовании: объясните проблему: пайп передаёт в stdin, а многие команды ожидают аргументы — xargs решает это. Знание флагов -I {}, -0, -P показывает практический опыт. Частый вопрос: «как безопасно удалить файлы с пробелами в именах?» — find ... -print0 | xargs -0 rm.