Предположим, я хочу удалить все файлы в каталоге, кроме одного с именем "notes.txt". Я бы сделал это с конвейером ls | grep -v "notes.txt" | xargs rm
. Зачем мне нужен xargs, если на выходе второго канала указан вход, который должен использовать rm?
Для сравнения, конвейер echo "#include <knowledge.h>" | cat > foo.c
вставляет отраженный текст в файл без использования xargs. В чем разница между этими двумя трубопроводами?
ls | grep -v "notes.txt" | xargs rm
для удаления все, кромеnotes.txt
или вообще, никогда не анализироватьls
вывод . Ваша команда прервется, если, например, в одном файле будет пробел. Более безопасный путь -rm !(notes.txt)
в Bash (сshopt -s extglob
сетом) илиrm ^notes.txt
в Zsh (сEXTENDED_GLOB
) и т. Д.find . -maxdepth 1 -mindepth 1 -print0 | xargs -0
вместоls | xargs
:-)Ответы:
Вы путаете два очень разных вида ввода: STDIN и аргументы. Аргументы представляют собой список строк, предоставляемых команде при ее запуске, обычно путем указания их после имени команды (например,
echo these are some arguments
илиrm file1 file2
). STDIN, с другой стороны, представляет собой поток байтов (иногда текст, иногда нет), который команда может (необязательно) прочитать после ее запуска. Вот несколько примеров (обратите внимание, что ониcat
могут принимать либо аргументы, либо STDIN, но это делает с ними разные вещи):xargs
можно рассматривать как преобразование входных данных в стиле STDIN в аргументы:echo
фактически делает более или менее обратное: он преобразует свои аргументы в STDOUT (который может быть передан в STDIN какой-то другой команды):источник
cat
принимает данные отSTDIN
иrm
не делает. Для таких команд вам нужноxargs
перебиратьSTDIN
построчно и выполнять команды с параметрами командной строки.источник