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