Zsh ve bash'deki döngüler için


57

Zsh'de bina döngüleri yapmanın iki alternatif yolu olduğunu fark ettim :

  1. for x (1 2 3); do echo $x; done
  2. for x in 1 2 3; do echo $x; done

Her ikisi de yazdırır:

1
2
3

Sorum şu, neden iki sözdizimi? Is $xfarklı yineleme nesne türüne bunların her birinde?

Does bash benzer ayrım yapmak?

Zeyilname:

Aşağıdaki neden çalışıyor ?:

#!/bin/zsh
a=1
b=2
c=5    

d=(a b c)    
for x in $d; do print $x;done

ama bu değil mi ?:

#!/bin/zsh
a=1
b=2
c=5

d=(a b c)    
# It complains with "parse error near `$d'"
for x $d; do print $x;done 

5
döngü için csh stili olan "çalışmaz" örneği için parantezleri kaçırıyorsunuzdur. for x ($d); do print $x; doneçalışacak ve sorunuzun başında numaralandırdığınız ilk sözdizimiyle eşleşecektir.
Tim Kennedy

1
Bu çok çılgınca - bu iki ifadenin - aslında her ikisi de "aynı şekilde çalışmıyor". Kelimenin tam anlamıyla kafamı etrafında alamıyorum! Bu kabuk tasarımcılarının sigara içtiği şeylerden bazılarını içmem gerekiyor ', lol.
alex grey

Dikkat et, başlangıçta göründüğünden daha fazla hikaye var. Sizi cevabımı kontrol etmeye davet ediyorum.
jasonleonhard

Başka kimsenin bahsettiğini görmedim, ancak her iki form da yapılmaması / yapılmamasına izin veriyor: for i ({0..4..2}) for j ({a..c}) echo "($i,$j)"= {0,2,4}x{a,b,c}. Noktalı virgüller en dıştaki döngüye uygulanır ve yönlendirmeler en içteki bölüme uygulanır ve bunu değiştirmeniz gerekirse, yalnızca ayraçlara ihtiyacınız vardır: for i ({0..4..2}) { for j ({a..c}) echo "($i,$j)" } | cat -n= {1,...,9}*({0,2,4}x{a,b,c}). Elbette döngülerinizi zsh genişlemesiyle birleştirebilirsiniz:for i ("("{0..4..2}","{a..c}")") echo $i
John P

Yanıtlar:


58

Döngüler gibi çeşitli karmaşık komut biçimlerinin zsh'de alternatif biçimleri vardır. Bu formlar çoğunlukla , zsh gençken oldukça yaygın olan ama şimdi ortadan kaybolduğu zaman oldukça yaygın olan C kabuğundan esinlenmiştir . Bu alternatif formlar normal formlar gibi çalışır, sadece farklı bir sözdizimidir. Biraz daha kısa, ama daha az net.

İçin standart formda forkomuta olduğunu for x in 1 2 3; do echo $x; doneve standart formu whilekomutu olduğunu while test …; do somecommand; done. Ksh, bash ve zsh alternatif bir biçime sahiptir for: tam sayıları numaralandırmak için Pascal veya C gibi dillerin for ((i = 0; i < 42; i++)); do somecommand; donedilimlerini taklit eder for. Zsh'da bulunan diğer egzotik formlar zsh'ye özgüdür (ancak genellikle csh'den esinlenilmiştir).


@Guilles'de çok teşekkürler. Hala biraz kafam karıştı. Spesifik olan hangisi zsh? Ayrıca, OPimin sonunda sözdizimleri arasında nasıl tercüme edileceğini bulamadığım bir örnek daha ekledim. Fark sadece sözdizimi ise, ek çalışmasını sağlamak için ekdeki ikinci betiği nasıl düzeltmeliyim?
Amelio Vazquez-Reina

3
@intrpc Güncellenmiş cevabımı görün. Son örneğinize göre, işe yaramadı çünkü for x $dyazdınız ve zsh ya yazdığınız ya inda (yazdığınız yeri bekliyor $d. Noktalama işaretleri ve ayrılmış sözcükler değişken bir genişlemeden gelemez, kabuk değişken genişlemelerde başlayabilmesi için önce ayrıştırılması gerekir.
Gilles 'SO- kötülük' dur

@ INTRPC her ikisi de zsh özgüdür. zsh, her ikisinin de melezi olduğundan, hem bourne, hem de hem de c-shell sözdizimini desteklemek için özel olarak tasarlanmıştır.
Tim Kennedy,

1
@ pseyfert Çalışıyor, ancak gösterdiğim formlara göre hiçbir avantajı yok: for (( … ))formdan daha az taşınabilir ve 3 büyükse çok fazla bellek kullanıyor.
Gilles 'SO- kötülük'

1
@ alpha_989 sh benzeri bir sözdiziminde dosonra gerekir ));. Zsh de başka sözdizimi kabul tek komuttur. Bu yüzden kabul ediyor . Bundan sonra görünce , şikayet etmez , çünkü sona ermesi gerekmedi. Kılavuzdaki "Karmaşık Komutlar İçin Alternatif Formlar" bölümüne bakın . for ((…)); COMMANDCOMMANDfor ((i = 1; i<100; i++)); ghi show $i | grep "log"donedo
Gilles 'SO- kötülük'
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.