Я знаю, що, даючи 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
тут ...)
Кращим способом вирішити його (IMO) було б:
в zsh
:
l=(a b c)
mycommand -f$^l
або використовуючи масив блискавки, щоб аргумент не був приєднаний до параметра:
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
не мають стиснути масив)
З подібними оболонками, подібними до Борна, як 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
його парний параметр.