Разница в том, какие данные принимает целевая программа.
Если вы просто используете канал, он получает данные по STDIN (стандартному входному потоку) в виде необработанной стопки данных, которую он может сортировать по одной строке за раз. Однако некоторые программы не принимают свои команды в стандартном режиме, они ожидают, что это будет прописано в аргументах команды. Например touch
принимает имя файла в качестве параметра в командной строке , например так: touch file1.txt
.
Если у вас есть программа , которая выводит имена файлов на стандартный вывод и хотите использовать их в качестве аргументов к touch
, вы должны использовать , xargs
который считывает данные потока STDIN и преобразует каждую строку в пространстве , разделенных аргументы команды.
Эти две вещи эквивалентны:
# touch file1.txt
# echo file1.txt | xargs touch
Не используйте, xargs
если вы точно не знаете, что он делает и зачем он нужен. Довольно часто случается, что есть лучший способ сделать работу, чем использовать xargs
для принудительного преобразования. Процесс конвертации также чреват потенциальными ловушками, такими как экранирование, расширение слов и т. Д.
xargs
и$(...)
) xargs гораздо безопаснее, чем подстановка команд. И я не могу вспомнить, чтобы когда-либо встречал законное имя файла с новой строкой в нем. Разве проблемы с подстановкой и раскрытием слов не связаны с подстановкой команд, а не с xargs?xargs -0
), что полезно в сочетании сfind -print0
.xargs
программа через оболочку с аргументами, разделенными пробелами, или она фактически создает список аргументов внутренне (например, для использования сexecv
/execp
)?-d \n
символ новой строки в качестве разделителя , хотя BSD xargs (OSX и др.) Не поддерживает эту опцию.Чтобы расширить уже предоставленные ответы,
xargs
можно сделать одну интересную вещь, которая становится все более важной в современной многоядерной и распределенной вычислительной среде: она может параллельно обрабатывать задания.Например:
будет кодировать * .wav => * .flac, используя три процесса одновременно (
-P 3
).источник
-exec
Параметр не будет обрабатывать задания параллельно.-0
аргумент toxargs
заставляет его считатьNULL
символ разделителем входного элемента.find -print0
выводить элементы, разделенные NULL. Это хорошая практика для имен файлов, которые могут содержать пробелы, кавычки или другие специальные символы.xargs особенно полезен, когда у вас есть список путей к файлам на stdin и вы хотите что-то с ними сделать. Например:
Давайте рассмотрим это шаг за шагом:
Другими словами, наш вход - это список путей, с которыми мы хотим что-то сделать.
Чтобы выяснить, что xargs делает с этими путями, нужно добавить
echo
перед вашей командой хороший трюк , например:-n 1
Аргумент заставит xargs превратить каждую строку в команду своих собственных.sed -i "s/color/colour/g"
Команда заменит все вхожденияcolor
сcolour
указанным файлом.Обратите внимание, что это работает, только если у вас нет пробелов в ваших путях. Если вы это сделаете, вы должны использовать пути с нулевым символом в конце как входные данные для xargs, передавая
-0
флаг. Пример использования будет:Который делает то же самое, что мы описали выше, но также работает, если в одном из путей есть пробел.
Это работает с любой командой, которая производит имена файлов в качестве вывода, такие как
find
илиlocate
. Если вам случится использовать его в git-репозитории с большим количеством файлов, возможно, было бы более эффективно использовать егоgit grep -l
вместоgit ls-files
, например, так:Команда
git grep -l "color" "*.tex"
выдаст список файлов «* .tex», содержащих фразу «color».источник
Ваш первый аргумент хорошо иллюстрирует разницу.
\ls | grep Cases | less
позволяет просматривать список имен файлов, созданныхls
иgrep
. Неважно, что это имена файлов, это просто текст.\ls | grep Cases | xargs less
позволяет просматривать файлы, имена которых создаются первой частью команды.xargs
принимает список имен файлов в качестве входных данных и команд на его командной строке, и выполняет команду с именами файлов на его командной строке.При рассмотрении вопроса об использовании
xargs
имейте в виду, что он ожидает, что входные данные отформатированы странным образом: с пробелами, разделенными пробелами\
,'
и"
используются для цитирования (необычным образом, поскольку\
не являются специальными внутренними кавычками). Используйте толькоxargs
если ваши имена файлов не содержат пробелов или\'"
.источник
xargs
есть-0, --null
возможность обойти проблему пробелов (весьма вероятно, что я узнал об этом от вас :), поэтому я предполагаю, что вы имеете в видуxarg
вызов no-options , но я озадачен вашей ссылкой на кавычки. У вас есть ссылка или пример по этому поводу? .. (пс.| xargs less
это удобный "трюк" +1 .. спасибо ..В вашем примере вам не нужно использовать
xargs
вообще, так какfind
будет делать точно и безопасно, что вы хотите сделать.Именно то, что вы хотите использовать,
find
это:В данном примере
-maxdepth 1
означает только поиск в текущем каталоге, не спустится в подкаталоги; По умолчанию find будет искать во всех подкаталогах (что часто и бывает), если вы не ограничите их maxdepth. Это{}
имя файла, который будет заменен на его месте, и+
это один из двух маркеров конца команды, другой - существо;
. Разница между ними состоит в том, что;
означает выполнение команды для каждого файла по одному, тогда как+
означает выполнение команды для всех файлов одновременно. Однако следует отметить, что ваша оболочка, вероятно , попытается интерпретировать;
себя, так что вам нужно будет , чтобы избежать его либо\;
или';'
. Да, уfind
этого есть несколько маленьких неприятностей, но его сила более чем компенсирует это.И то,
find
и другоеxargs
сложно освоить сначала. Чтобы помочь вам узнать,xargs
попробуйте использовать опцию-p
или,--interactive
которая покажет вам команду, которую она собирается выполнить, и подскажет вам, хотите ли вы ее запустить.Точно так же
find
вы можете использовать-ok
вместо,-exec
чтобы предложить вам, хотите ли вы выполнить команду.Однако бывают случаи, когда
find
не удается сделать все, что вы хотите, и это то, что вам нужноxargs
. Команда-exec
примет только один случай{}
появления, поэтому, если вы получите сообщение об ошибке,find -type f -exec cp {} {}.bak \;
вы можете вместо этого сделать это так :find -type f -print0 | xargs -0 -l1 -IX cp X X.bak
Вы можете узнать больше о командах запуска в руководстве GNU Findutils .
Кроме того, я упомянул, что
find
безопасно делает то, что вы хотите, потому что, когда вы имеете дело с файлами, вы столкнетесь с пробелами и другими символами, которые вызовут проблемы,xargs
если вы не используете опцию-0
или--null
вместе с чем-то, что генерирует входные элементы, оканчивающиеся нулевым символом вместо пробелов.источник
'
или"
могут быть проблематичными, тогда какfind
будут обрабатывать эти случаи без проблем.xargs
(наряду сfind
,sort
,du
,uniq
,perl
и несколько других) принимает параметр командной строки , чтобы сказать «STDIN есть список файлов, разделенных NUL (0x00) байт». Это позволяет легко обрабатывать имена файлов с пробелами и другими забавными символами в них. Имена файлов не содержат NUL.источник