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 b
ve c
içermez. :)
GNU ile findutil
genel 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
, b
ya 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 xargs
listeyi böler ve başka bir kopyasını çalıştırır mycommand
ve bunun sonlandırılmamış olarak bırakılması riski vardır -f
. Bu durum hakkında endişeleniyorsanız, xargs -0
yukarıdaki sonuncuyu böyle bir şeyle değiştirebilirsiniz :
... | xargs -x -0 mycommand
Bu sorunu çözmez, ancak mycommand
argümanlar listesi çok uzun olduğunda çalışmayı iptal eder.
mycommand
. Her zaman -x
sonuncuya ekleyebilirsiniz xargs
.
xargs
ve 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 . :)
-f
ve 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 find
sunuyor -exec
size sağlayan argüman, inşa bir komut satırı, 's cezası. ( mycommand
Bir kereden fazla çalışmasına izin verildiği sürece . Değilse, o zaman xargs
burada 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, l
dizi 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 rc
ve fish
dizi sıkıştırması yok)
Eski tarz Bourne benzeri mermilerle bash
her 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, set
döngü büyük olasılıkla her seferinde birikmiş arg listesini kopyalar ve yeniden ayrıştırır (O (n ^ 2)).
ARG_MAX
ve-f
ayrılma riski oldukça çirkin .