Biliyorum, verilen l="a b c",
echo $l | xargs ls
verim
ls a b c
Hangi yapı
mycommand -f a -f b -f c
Biliyorum, verilen l="a b c",
echo $l | xargs ls
verim
ls a b c
Hangi yapı
mycommand -f a -f b -f c
Yanıtlar:
Bunu yapmanın bir yolu:
echo "a b c" | xargs printf -- '-f %s\n' | xargs mycommand
Bu a, boşluklar, yeni satırlar, tırnak işaretleri veya ters eğik çizgiler içerdiğini varsayar bve ciçermez. :)
GNU ile findutilgenel durumu ele alabilirsiniz, ancak biraz daha karmaşıktır:
echo -n "a|b|c" | tr \| \\0 | xargs -0 printf -- '-f\0%s\0' | xargs -0 mycommand
Sen yerini alabilecek |bu görünmez, diğer bazı karakter ile ayırıcı a, bya c.
Düzenleme: As @MichaelMol notlar, tartışmaların çok uzun bir liste ile geçirilebilir argümanlar maksimum uzunluğu taşan bir riski vardır mycommand. Bu olduğunda, son xargslisteyi böler ve başka bir kopyasını çalıştırır mycommandve bunun sonlandırılmamış olarak bırakılması riski vardır -f. Bu durum hakkında endişeleniyorsanız, xargs -0yukarıdaki sonuncuyu böyle bir şeyle değiştirebilirsiniz :
... | xargs -x -0 mycommand
Bu sorunu çözmez, ancak mycommandargümanlar listesi çok uzun olduğunda çalışmayı iptal eder.
mycommand. Her zaman -xsonuncuya ekleyebilirsiniz xargs.
xargsve sadece kullanılabiliyorsa kullanmaktır find. Bu çözüm tehlikelidir; en azından cevabınızdaki başarısızlık durumunda uyarmalısınız.
findÖzellikle ilk argümanlar dosya adı olmadığında nasıl daha iyi bir genel çözüm olacağını göremiyorum . :)
-fve lsörnekleme için kullanılan örnek bir araçla , @ kullanıcı olmayanların dosya adları ile uğraştığını öne sürer . Ve verilen findsunuyor -execsize sağlayan argüman, inşa bir komut satırı, 's cezası. ( mycommandBir kereden fazla çalışmasına izin verildiği sürece . Değilse, o zaman xargsburada kullanımı ile ilgili başka bir sorunumuz var ...)
Bunu ele almanın daha iyi bir yolu (IMO):
içinde zsh:
l=(a b c)
mycommand -f$^l
veya argüman seçeneğe eklenmeyecek şekilde dizi sıkıştırma özelliğini kullanarak:
l=(a b c) o=(-f)
mycommand "${o:^^l}"
Bu şekilde, ldizi boş öğeler veya boşluk veya başka herhangi bir sorunlu karakter içeren öğeler içeriyorsa yine de çalışır xargs. Misal:
$ l=(a '' '"' 'x y' c) o=(-f)
$ printf '<%s>\n' "${o:^^l}"
<-f>
<a>
<-f>
<>
<-f>
<">
<-f>
<x y>
<-f>
<c>
içinde rc:
l=(a b c)
mycommand -f$l
içinde fish:
set l a b c
mycommand -f$l
(AFAIK rcve fishdizi sıkıştırması yok)
Eski tarz Bourne benzeri mermilerle bashher zaman yapabilirsin (yine de $@dizinin elemanlarında herhangi bir karaktere izin verir ):
set -- a b c
for i do set -- "$@" -f "$i"; shift; done
mycommand "$@"
for i; do args+=('-f' "$i");done; mycommand "${args[@]}". IDK bu daha hızlıysa, ancak bir diziye 2 öğe eklemek O (n) gibi görünüyor, setdöngü büyük olasılıkla her seferinde birikmiş arg listesini kopyalar ve yeniden ayrıştırır (O (n ^ 2)).
ARG_MAXve-fayrılma riski oldukça çirkin .