So che, dato l="a b c",
echo $l | xargs ls
i rendimenti
ls a b c
Quale costrutto produce
mycommand -f a -f b -f c
So che, dato l="a b c",
echo $l | xargs ls
i rendimenti
ls a b c
Quale costrutto produce
mycommand -f a -f b -f c
Risposte:
Un modo per farlo:
echo "a b c" | xargs printf -- '-f %s\n' | xargs mycommand
Ciò presuppone a, be cnon contengono spazi vuoti, a capo, virgolette o backslash. :)
Con GNU findutilpuoi gestire il caso generale, ma è leggermente più complicato:
echo -n "a|b|c" | tr \| \\0 | xargs -0 printf -- '-f\0%s\0' | xargs -0 mycommand
È possibile sostituire il |separatore con qualche altro personaggio, che non figura in a, bo c.
Modifica: Come osserva @MichaelMol , con un elenco molto lungo di argomenti c'è il rischio di traboccare la lunghezza massima degli argomenti a cui è possibile passare mycommand. Quando ciò accade, l'ultimo xargsdivide l'elenco e ne esegue un'altra copia mycommand, e c'è il rischio che rimanga non terminato -f. Se ti preoccupi di quella situazione, potresti sostituire l'ultimo xargs -0sopra con qualcosa del genere:
... | xargs -x -0 mycommand
Questo non risolverà il problema, ma si interromperà mycommandquando l'elenco degli argomenti diventa troppo lungo.
mycommand. Puoi sempre aggiungere -xl'ultimo xargs.
xargsaffatto, e usare solo findse può essere usata. Questa soluzione è pericolosa; dovresti almeno avvisare del caso di fallimento nella tua risposta.
findsarebbe una soluzione generale migliore, in particolare quando gli argomenti iniziali non sono nomi di file. :)
-fe con uno strumento di esempio lsusato per l'illustrazione, @ non-un-utente ha a che fare con nomi di file. E dato findoffre l' -execargomento, che ti permette di costruire una riga di comando, va bene. (Finché mycommandè consentito eseguire più di una volta. In caso contrario, abbiamo un altro problema con l'uso di xargsqui ...)
Un modo migliore per affrontarlo (IMO) sarebbe:
in zsh:
l=(a b c)
mycommand -f$^l
o usando l'array zipping in modo che l'argomento non sia associato all'opzione:
l=(a b c) o=(-f)
mycommand "${o:^^l}"
In questo modo, funziona ancora se l' larray contiene elementi vuoti o elementi contenenti spazi o qualsiasi altro carattere problematico per xargs. Esempio:
$ l=(a '' '"' 'x y' c) o=(-f)
$ printf '<%s>\n' "${o:^^l}"
<-f>
<a>
<-f>
<>
<-f>
<">
<-f>
<x y>
<-f>
<c>in rc:
l=(a b c)
mycommand -f$lin fish:
set l a b c
mycommand -f$l(AFAIK rce fishnon ha zippatura di array)
Con gusci di tipo Bourne vecchio stile come bash, potresti sempre fare (permettendo comunque qualsiasi carattere negli elementi $@dell'array):
set -- a b c
for i do set -- "$@" -f "$i"; shift; done
mycommand "$@"
for i; do args+=('-f' "$i");done; mycommand "${args[@]}". IDK se questo è più veloce, ma l'aggiunta di 2 elementi a un array sembra che dovrebbe essere O (n), mentre il tuo setloop probabilmente copia e analizza nuovamente l'elenco arg accumulato ogni volta (O (n ^ 2)).
ARG_MAXe avere un-fparametro separato dal suo parametro associato.