Bash'ta, bir for döngüsünün döngü kontrolünde bir tamsayı değişkeni kullanmak mümkün müdür?


65

Aşağıdaki bash betiğim var:

#!/bin/bash

upperlim=10

for i in {0..10}
do
echo $i
done

for i in {0..$upperlim}
do
echo $i
done

İlk for(döngü olmadan değişken upperlimdöngü kontrolünde) çalışıyor, ancak ikinci for(döngü ile değişken upperlimdöngü kontrolünde) değildir. İkinci fordöngüyü değiştirebilmem için herhangi bir yöntem var mı ? Zaman ayırdığınız için teşekkürler.


4
hm, for i in {0..$((upperlim))}; do echo $i; doneçalışmıyor bile
Bonsi Scott 10:12

ve +1 çünkü bu davranışı ilginç buluyorum
Bonsi Scott 10:12


Buna cevap veren harici bir link: cyberciti.biz/faq/…
kon psych

Yanıtlar:


62

Bunun nedeni, olayların bash içinde gerçekleştiği düzendir. Parantez genişlemesi değişkenler genişletilmeden önce gerçekleşir . Hedefinize ulaşmak için, döngü için C-stili kullanmanız gerekir:

upperlim=10

for ((i=0; i<=upperlim; i++)); do
   echo "$i"
done

1
Ve için çalışır zsh(ancak yanı csh, tcsh).
matematik

29

Bunu kendi tarzınızda tamamlayıcılar dışında hiçbir şey kullanarak tamamlamak için eval kullanmanız gerekir:

d=12

for i in `eval echo {0..$d}`
do
echo $i
done

Ancak seq:

lowerlimit=0
upperlimit=12

for i in $(seq $lowerlimit $upperlimit)
do
echo $i
done

Şahsen kullanımını seqdaha okunaklı buluyorum .


"Yerleşik" için mi? seqharici bir komuttur ve bash'ın bulunduğu her yerde kullanılamaz.
Ürdün

9
@ jordanm: Tüm yapıları bash ile kullanmak için. Sonra "ama beraber seq" dedim , bunun yerleşik olmadığını kabul ederek.
Jodie C

Brace genişlemesinin yerleşik olması, buradaki sorun değil. readörneğin bir yerleşiktir, ancak bunun için bir neden yoktur eval.
Ürdün

1
Yerleşikler hiç sorun değil. Asker için bir bash çözümü sunmak istedim. Bu konuda tartışmaya devam etmek istiyorsan sohbete al; Yorumlar bu tür şeyler için iyi değil
Jodie C

8

POSIX yolu

Taşınabilirliği önemsiyorsanız POSIX standardındaki örneği kullanın :

i=2
END=5
while [ $i -le $END ]; do
    echo $i
    i=$(($i+1))
done

Çıktı:

2
3
4
5

POSIX olmayan şeyler :


1

Yaklaşımdaki genişleme parametre genişlemeden önce gerçekleştiği için yaklaşımınız çalışmayacak. Değişkeni daha önce genişletmeniz gerekir.

Eval ile çalışabilirsiniz :

upperlim=10
eval '
        for i in {0..'"$upperlim"'}
        do
                echo $i
        done
'

İle birlikte döngü :

upperlim=10
#with while
start=0
while [[ $start -le $upperlim ]]
do
    echo "$start"
    ((start = start + 1))
done

Ayrıca seq komutu ile yapabilirsiniz :

upperlim=10
#seq
for i in $(seq "$upperlim"); do
  echo "$i"
done

Çalıştırmak for i in {0..$upperlim}istiyorsanız kornshell kullanmanız gerekir. Örneğin:

#!/bin/ksh
upperlim=10

for i in {0..$upperlim}
do
        echo $i
done
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.