Aşağıdaki gibi temel döngüyü arıyorum:
for(int i = 0; i < MAX; i++) {
doSomething(i);
}
ama bash için.
Aşağıdaki gibi temel döngüyü arıyorum:
for(int i = 0; i < MAX; i++) {
doSomething(i);
}
ama bash için.
Yanıtlar:
for ((i = 0 ; i < max ; i++ )); do echo "$i"; done
ArrayLength=${#array[@]}
onu burada yerine nasıl kullanırız max
?
Bash for
, bir değişkenden (yineleyici) ve yineleyicinin yineleyeceği bir sözcük listesinden oluşur.
Dolayısıyla, sınırlı bir kelime listeniz varsa, bunları aşağıdaki söz dizimine eklemeniz yeterlidir:
for w in word1 word2 word3
do
doSomething($w)
done
Muhtemelen bazı sayılar boyunca yineleme yapmak istersiniz, böylece sizin seq
için bir sayı listesi oluşturmak için komutu kullanabilirsiniz : (örneğin 1'den 100'e kadar)
seq 1 100
ve FOR döngüsünde kullanın:
for n in $(seq 1 100)
do
doSomething($n)
done
Not $(...)
sözdizimi. Bu bir bash davranışıdır, çıktıyı bir komuttan (bizim durumumuzda seq
) diğerine (the for
) geçirmenize izin verir.
Bu, bazı yollardaki tüm dizinleri yinelemeniz gerektiğinde gerçekten yararlıdır, örneğin:
for d in $(find $somepath -type d)
do
doSomething($d)
done
Listeleri oluşturmak için olasılıklar sonsuzdur.
Bash 3.0+ şu sözdizimini kullanabilir:
for i in {1..10} ; do ... ; done
.. bu, diziyi genişletmek için harici bir program (örneğin seq 1 10
) üretmekten kaçınır .
Tabii ki, bu for(())
çözümle aynı soruna sahiptir, bash'a ve hatta belirli bir versiyona bağlı (bu sizin için önemliyse).
Yerleşik bash
yardımı deneyin :
$ help for
for: for NAME [in WORDS ... ;] do COMMANDS; done
The `for' loop executes a sequence of commands for each member in a
list of items. If `in WORDS ...;' is not present, then `in "$@"' is
assumed. For each element in WORDS, NAME is set to that element, and
the COMMANDS are executed.
for ((: for (( exp1; exp2; exp3 )); do COMMANDS; done
Equivalent to
(( EXP1 ))
while (( EXP2 )); do
COMMANDS
(( EXP3 ))
done
EXP1, EXP2, and EXP3 are arithmetic expressions. If any expression is
omitted, it behaves as if it evaluates to 1.
#! /bin/bash
function do_something {
echo value=${1}
}
MAX=4
for (( i=0; i<MAX; i++ )) ; {
do_something ${i}
}
İşte eski kabuklarda da işe yararken, büyük sayılar için verimli olmaya devam eden bir örnek:
Z=$(date) awk 'BEGIN { for ( i=0; i<4; i++ ) { print i,"hello",ENVIRON["Z"]; } }'
Ama içinde yararlı şeyler yapmakta bol şans awk
: Bir awk komut dosyasında kabuk değişkenlerini nasıl kullanabilirim?
do
/ done
çift yerine küme parantezlerinin kullanılmasıdır .
Genellikle standart for döngüsünde küçük bir varyant kullanmayı severim. Bunu genellikle bir dizi uzak ana bilgisayarda bir komut çalıştırmak için kullanırım. Sayısal olmayan for-döngüler oluşturmama izin veren döngüler oluşturmak için bash'ın küme ayracı genişletmesinden yararlanıyorum.
Misal:
Uptime komutunu 1-5 ön uç ana bilgisayarlarında ve 1-3 arka uç ana bilgisayarlarında çalıştırmak istiyorum:
% for host in {frontend{1..5},backend{1..3}}.mycompany.com
do ssh $host "echo -n $host; uptime"
done
Bunu genellikle yukarıdaki daha okunaklı sürüm yerine satırların sonlarında noktalı virgül bulunan tek satırlı bir komut olarak çalıştırırım. Temel kullanım düşüncesi, kaşlı ayraçların bir dizeye eklenecek birden fazla değeri belirlemenize izin vermesidir (örn. Pre {foo, bar} post, prefoopost, prebarpost'ta) ve çift noktaları kullanarak sayma / dizilere izin vermesidir (bir. .z vb.) Bununla birlikte, çift dönem sözdizimi, bash 3.0'ın yeni bir özelliğidir; önceki sürümler bunu desteklemeyecektir.
sadece bash ile ilgileniyorsanız, yukarıda sunulan "for ((...))" çözümü en iyisidir, ancak tüm aygıtlarda çalışacak POSIX SH uyumlu bir şey istiyorsanız, "ifade" kullanmanız gerekir ve "while", çünkü "(())" veya "seq" veya "i = i + 1" çeşitli kabuklar arasında o kadar da taşınabilir değil
Dosyaları işlemek için her zaman bunun varyasyonlarını kullanıyorum ...
* .log dosyasındaki dosyalar için; do echo "Aşağıdakilerle şeyler yapın: $ files"; echo "Daha fazla şey yapın: $ files"; bitti;
İlgilendiğiniz şey dosya listelerini işlemekse , dosyalar için -execdir seçeneğine bakın .