Я знаю, що, даючи 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його парний параметр.