Saya tahu itu, mengingat l="a b c"
,
echo $l | xargs ls
hasil panen
ls a b c
Yang membangun menghasilkan
mycommand -f a -f b -f c
Saya tahu itu, mengingat l="a b c"
,
echo $l | xargs ls
hasil panen
ls a b c
Yang membangun menghasilkan
mycommand -f a -f b -f c
Jawaban:
Salah satu cara untuk melakukannya:
echo "a b c" | xargs printf -- '-f %s\n' | xargs mycommand
Ini mengasumsikan a
,, b
dan c
tidak mengandung blank, baris baru, kutipan atau garis miring terbalik. :)
Dengan GNU findutil
Anda dapat menangani kasus umum, tetapi sedikit lebih rumit:
echo -n "a|b|c" | tr \| \\0 | xargs -0 printf -- '-f\0%s\0' | xargs -0 mycommand
Anda dapat mengganti |
pemisah dengan beberapa karakter lain, yang tidak muncul dalam a
, b
atau c
.
Sunting: Seperti catatan @MichaelMol , dengan daftar argumen yang sangat panjang ada risiko meluap-luap dari panjang argumen maksimum yang bisa diteruskan mycommand
. Ketika itu terjadi, yang terakhir xargs
akan membagi daftar dan menjalankan salinan lain mycommand
, dan ada risiko itu meninggalkan yang tidak termotivasi -f
. Jika Anda khawatir tentang situasi itu, Anda bisa mengganti yang terakhir di xargs -0
atas dengan sesuatu seperti ini:
... | xargs -x -0 mycommand
Ini tidak akan menyelesaikan masalah, tetapi akan dibatalkan mycommand
saat daftar argumen terlalu panjang.
mycommand
. Anda selalu bisa menambahkan -x
yang terakhir xargs
.
xargs
sama sekali, dan gunakan saja find
jika dapat digunakan. Solusi ini berbahaya; Anda setidaknya harus memperingatkan kasus kegagalan dalam jawaban Anda.
find
solusi umum yang lebih baik, terutama ketika argumen awal bukan nama file. :)
-f
, dan dengan alat contoh yang ls
digunakan untuk ilustrasi, @ not-a-user berurusan dengan nama file. Dan diberikan find
menawarkan -exec
argumen, yang memungkinkan Anda untuk membangun command-line, tidak apa-apa. (Selama mycommand
diizinkan untuk mengeksekusi lebih dari sekali. Jika tidak, maka kita memiliki masalah lain dengan penggunaan di xargs
sini ...)
Cara yang lebih baik untuk mengatasinya (IMO) adalah:
di zsh
:
l=(a b c)
mycommand -f$^l
atau menggunakan array zip sehingga argumen tidak dilampirkan ke opsi:
l=(a b c) o=(-f)
mycommand "${o:^^l}"
Dengan begitu, masih berfungsi jika l
array berisi elemen kosong atau elemen yang berisi spasi atau karakter bermasalah lainnya xargs
. Contoh:
$ l=(a '' '"' 'x y' c) o=(-f)
$ printf '<%s>\n' "${o:^^l}"
<-f>
<a>
<-f>
<>
<-f>
<">
<-f>
<x y>
<-f>
<c>
di rc
:
l=(a b c)
mycommand -f$l
di fish
:
set l a b c
mycommand -f$l
(AFAIK, rc
dan fish
tidak memiliki zipping array)
Dengan kerang mirip Bourne gaya lama bash
, Anda selalu dapat melakukannya (masih mengizinkan karakter apa pun di elemen $@
array):
set -- a b c
for i do set -- "$@" -f "$i"; shift; done
mycommand "$@"
for i; do args+=('-f' "$i");done;
mycommand "${args[@]}"
. IDK jika ini lebih cepat, tetapi menambahkan 2 elemen ke array sepertinya itu harus O (n), sementara set
loop Anda mungkin menyalin dan mem-parsing daftar arg akumulasi setiap waktu (O (n ^ 2)).
ARG_MAX
dan-f
memisahkan dari parameter yang dipasangkan.