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
źródło
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
Jednym ze sposobów na to:
echo "a b c" | xargs printf -- '-f %s\n' | xargs mycommand
Zakłada się a
, b
i c
nie zawiera spacji, znaków nowej linii, cytatów ani ukośników odwrotnych. :)
Z GNU findutil
moż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
, b
lub 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 xargs
podzieli 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 -0
powyższych przez coś takiego:
... | xargs -x -0 mycommand
To nie rozwiąże problemu, ale przerwie działanie, mycommand
gdy lista argumentów będzie zbyt długa.
ARG_MAX
i-f
oddzielenie od sparowanego parametru.mycommand
. Zawsze możesz dodać-x
do ostatniegoxargs
.xargs
, a po prostu użyj,find
jeśli można go użyć. To rozwiązanie jest niebezpieczne; powinieneś przynajmniej ostrzec przypadek niepowodzenia w swojej odpowiedzi.find
byłoby lepszym ogólnym rozwiązaniem, zwłaszcza gdy początkowe argumenty nie są nazwami plików. :)-f
i przykładowym narzędziemls
używanym do ilustracji @ not-a-user zajmuje się nazwami plików. I biorąc pod uwagęfind
oferuje-exec
argument, który pozwala zbudować wiersz poleceń, jest w porządku. (Tak długo, jakmycommand
jest to dozwolone, aby wykonać więcej niż jeden raz. Jeśli tak nie jest, mamy kolejny problem z użyciemxargs
tutaj ...)Lepszym sposobem rozwiązania tego problemu (IMO) byłoby:
w
zsh
:lub za pomocą kompresji tablicy, aby argument nie był dołączony do opcji:
W ten sposób nadal działa, jeśli
l
tablica zawiera puste elementy lub elementy zawierające spacje lub inny problematyczny znakxargs
. Przykład:w
rc
:w
fish
:(AFAIK
rc
ifish
nie 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):źródło
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 twojaset
pętla prawdopodobnie kopiuje i ponownie analizuje zgromadzoną listę arg za każdym razem (O (n ^ 2)).