Wiem to, biorąc pod uwagę l="a b c",
echo $l | xargs ls
daje
ls a b c
Który konstrukt daje
mycommand -f a -f b -f c
Wiem to, biorąc pod uwagę l="a b c",
echo $l | xargs ls
daje
ls a b c
Który konstrukt daje
mycommand -f a -f b -f c
Odpowiedzi:
Jednym ze sposobów na to:
echo "a b c" | xargs printf -- '-f %s\n' | xargs mycommand
Zakłada się a, bi cnie zawiera spacji, znaków nowej linii, cytatów ani ukośników odwrotnych. :)
Z GNU findutilmożesz poradzić sobie z ogólnym przypadkiem, ale jest to nieco bardziej skomplikowane:
echo -n "a|b|c" | tr \| \\0 | xargs -0 printf -- '-f\0%s\0' | xargs -0 mycommand
Można wymienić |separator z jakimś innym charakterze, że nie pojawi się a, blub c.
Edycja: Jak zauważa @MichaelMol , przy bardzo długiej liście argumentów istnieje ryzyko przepełnienia maksymalnej długości argumentów, które można przekazać mycommand. Kiedy tak się stanie, ostatni xargspodzieli listę i uruchomi kolejną kopię mycommand, i istnieje ryzyko, że pozostanie ona nieskończona -f. Jeśli martwisz się tą sytuacją, możesz zastąpić ostatnią z xargs -0powyższych przez coś takiego:
... | xargs -x -0 mycommand
To nie rozwiąże problemu, ale przerwie działanie, mycommandgdy lista argumentów będzie zbyt długa.
mycommand. Zawsze możesz dodać -xdo ostatniego xargs.
xargs, a po prostu użyj, findjeśli można go użyć. To rozwiązanie jest niebezpieczne; powinieneś przynajmniej ostrzec przypadek niepowodzenia w swojej odpowiedzi.
findbyłoby lepszym ogólnym rozwiązaniem, zwłaszcza gdy początkowe argumenty nie są nazwami plików. :)
-fi przykładowym narzędziem lsużywanym do ilustracji @ not-a-user zajmuje się nazwami plików. I biorąc pod uwagę findoferuje -execargument, który pozwala zbudować wiersz poleceń, jest w porządku. (Tak długo, jak mycommandjest to dozwolone, aby wykonać więcej niż jeden raz. Jeśli tak nie jest, mamy kolejny problem z użyciem xargstutaj ...)
Lepszym sposobem rozwiązania tego problemu (IMO) byłoby:
w zsh:
l=(a b c)
mycommand -f$^l
lub za pomocą kompresji tablicy, aby argument nie był dołączony do opcji:
l=(a b c) o=(-f)
mycommand "${o:^^l}"
W ten sposób nadal działa, jeśli ltablica zawiera puste elementy lub elementy zawierające spacje lub inny problematyczny znak xargs. Przykład:
$ l=(a '' '"' 'x y' c) o=(-f)
$ printf '<%s>\n' "${o:^^l}"
<-f>
<a>
<-f>
<>
<-f>
<">
<-f>
<x y>
<-f>
<c>
w rc:
l=(a b c)
mycommand -f$l
w fish:
set l a b c
mycommand -f$l
(AFAIK rci fishnie ma zipowania tablicy)
Dzięki starym powłokom podobnym do Bourne'a bash, zawsze możesz to zrobić (nadal dopuszczając dowolny znak w elementach $@tablicy):
set -- a b c
for i do set -- "$@" -f "$i"; shift; done
mycommand "$@"
for i; do args+=('-f' "$i");done; mycommand "${args[@]}". IDK, jeśli jest to szybsze, ale dodanie 2 elementów do tablicy wydaje się, że powinno to być O (n), podczas gdy twoja setpętla prawdopodobnie kopiuje i ponownie analizuje zgromadzoną listę arg za każdym razem (O (n ^ 2)).
ARG_MAXi-foddzielenie od sparowanego parametru.