Я знаю, что, учитывая l="a b c"
,
echo $l | xargs ls
доходность
ls a b c
Какая конструкция дает
mycommand -f a -f b -f c
источник
Я знаю, что, учитывая l="a b c"
,
echo $l | xargs ls
доходность
ls a b c
Какая конструкция дает
mycommand -f a -f b -f c
Один из способов сделать это:
echo "a b c" | xargs printf -- '-f %s\n' | xargs mycommand
Это предполагает a
, b
и c
не содержат пробелы, переводы строк, кавычки или слэш. :)
С GNU findutil
вы можете справиться с общим случаем, но это немного сложнее:
echo -n "a|b|c" | tr \| \\0 | xargs -0 printf -- '-f\0%s\0' | xargs -0 mycommand
Вы можете заменить |
разделитель с каким - либо другим символом, который не появляется в a
, b
или c
.
Редактировать: как отмечает @MichaelMol , с очень длинным списком аргументов существует риск переполнения максимальной длины аргументов, которые могут быть переданы mycommand
. Когда это произойдет, последний xargs
разделит список и запустит еще одну копию mycommand
, и есть риск, что он останется неопределенным -f
. Если вы беспокоитесь об этой ситуации, вы можете заменить последнее xargs -0
выше чем-то вроде этого:
... | xargs -x -0 mycommand
Это не решит проблему, но прервет работу, mycommand
когда список аргументов станет слишком длинным.
ARG_MAX
и получить-f
отдельный от своего парного параметра риск .mycommand
. Вы всегда можете добавить-x
к последнемуxargs
.xargs
вообще, а просто использовать,find
если оно может быть использовано. Это решение опасно; Вы должны по крайней мере предупредить о случае отказа в своем ответе.find
было бы лучше общее решение, особенно когда начальные аргументы не являются именами файлов. :)-f
и с примером инструмента,ls
используемого для иллюстрации, @ not-a-user имеет дело с именами файлов. И учитываяfind
предлагает-exec
аргумент, который позволяет вам создавать командную строку, это нормально. (Покаmycommand
разрешено выполнять более одного раза. Если это не так, у нас есть еще одна проблема с использованиемxargs
здесь ...)Лучший способ решить эту проблему (ИМО) будет:
в
zsh
:или используя zip-массив, чтобы аргумент не был прикреплен к опции:
Таким образом, это все еще работает, если
l
массив содержит пустые элементы или элементы, содержащие пробелы или любой другой проблемный символ дляxargs
. Пример:в
rc
:в
fish
:(AFAIK,
rc
и неfish
имеют архива массива)С подобными Bourne-подобными оболочками в старом стиле
bash
вы всегда можете это сделать (по-прежнему допуская любой символ в элементах$@
массива):источник
for i; do args+=('-f' "$i");done;
mycommand "${args[@]}"
, IDK, если это быстрее, но добавление 2 элементов в массив выглядит так, как будто это должно быть O (n), в то время как вашset
цикл, вероятно, копирует и повторно анализирует накопленный список аргументов каждый раз (O (n ^ 2)).