Мне кажется, что все существующие ответы на этой странице неверны, в том числе отмеченные как правильные. Это связано с тем, что вопрос неоднозначно сформулирован.
Резюме: Если вы хотите, чтобы выполнить команду «ровно один раз для каждой строки ввода заданного,» передавая всю строку (без перевода строки) в команде как один аргумент, то это лучший UNIX-совместимый способ сделать это:
... | tr '\n' '\0' | xargs -0 -n1 ...
GNU xargs
может иметь или не иметь полезных расширений, которые позволяют избавиться от tr
, но они не доступны на OS X и других системах UNIX.
Теперь для долгого объяснения ...
Есть два вопроса, которые следует принимать во внимание при использовании xargs:
- , как делает это разделить вклад в «аргументы»; и
- сколько аргументов для передачи дочерней команды за раз.
Чтобы проверить поведение xargs, нам нужна утилита, которая показывает, сколько раз она выполняется и сколько аргументов. Я не знаю, если есть стандартная утилита, чтобы сделать это, но мы можем закодировать его довольно легко в Баш:
#!/bin/bash
echo -n "-> "; for a in "[email protected]"; do echo -n "\"$a\" "; done; echo
Предполагая, что вы сохраните его как show
в текущем каталоге и сделать его исполняемым, вот как это работает:
$ ./show one two 'three and four'
-> "one" "two" "three and four"
Теперь, если первоначальный вопрос действительно о пункте 2 выше (как я думаю, что это, после прочтения его несколько раз более), и это следует читать, как это (изменения выделены жирным шрифтом):
Как я могу заставить xargs выполнить команду ровно один раз для каждого аргумента введенного ввода? Его поведение по умолчанию заключается в том, чтобы поместить вход в аргументы и выполнить команду как можно меньше, передав несколько аргументов каждому экземпляру.
тогда ответ -n 1
.
Давайте сравним поведение по умолчанию xargs', который расщепляет ввод вокруг пробелов и вызывает команду в несколько раз, как это возможно:
$ echo one two 'three and four' | xargs ./show
-> "one" "two" "three" "and" "four"
и его поведение с -n 1
:
$ echo one two 'three and four' | xargs -n 1 ./show
-> "one"
-> "two"
-> "three"
-> "and"
-> "four"
Если, с другой стороны, исходный вопрос состоял в том, что входное расщепление точки 1. Это должно было быть прочитано так (многие приходят сюда, похоже, считают, что это так, или путают эти два вопроса):
Как я могу сделать xargs выполнить команду с точно один аргумент для каждой строки ввода заданного? Его поведение по умолчанию заключается в разделении строк вокруг пробелов.
то ответ более тонкий.
Можно было бы подумать, что -L 1
может помочь, но, оказывается, он не изменяет разбор аргументов.Он только выполняет команду один раз для каждой строки ввода, с таким количеством аргументов, как было там, на входной линии:
$ echo $'one\ntwo\nthree and four' | xargs -L 1 ./show
-> "one"
-> "two"
-> "three" "and" "four"
Не только это, но если строка заканчивается пробелом, оно добавляется к следующему:
$ echo $'one \ntwo\nthree and four' | xargs -L 1 ./show
-> "one" "two"
-> "three" "and" "four"
Понятно, что -L
не касается изменения способа, в котором xargs разбивает входные данные на аргументы.
Единственный аргумент, который делает это кросс-платформенным способом (за исключением GNU-расширений), - -0
, который разбивает входные данные вокруг байтов NUL.
Тогда, это просто вопрос о переводе пустых строк в NUL с помощью tr
:
$ echo $'one \ntwo\nthree and four' | tr '\n' '\0' | xargs -0 ./show
-> "one " "two" "three and four"
Теперь аргумент синтаксический выглядит все в порядок, в том числе конечных пробельных символов.
Наконец, если вы комбинируете этот метод с -n 1
, вы получите ровно одно исполнение команды на входную строку, независимо от того, какой у вас есть вход, который может быть еще одним способом взглянуть на исходный вопрос (возможно, наиболее интуитивно понятный, учитывая заголовок):
$ echo $'one \ntwo\nthree and four' | tr '\n' '\0' | xargs -0 -n1 ./show
-> "one "
-> "two"
-> "three and four"
В примере вы предоставляете, `найти/путь типа F -delete` будет еще больше эффективный :) – tzot 2011-12-14 08:34:25
постарайтесь не использовать xargs ... – Naib 2015-03-02 10:04:04
OP, я знаю, что этот вопрос очень старый, но он все же появляется на Google и IMHO, принятый ответ неверен. См. Мой более длинный ответ ниже. – Tobia 2015-03-02 10:11:35