Giriş
Bash betiklerinde dizilerle çalışmak, özellikle de dizilerin uzunluğunu bulma, içerisinde değer arama, dilimleme veya elemanların sırasını değiştirme gibi işlemler yaparken bazen karmaşık görünebilir. Bash, bu işlemleri desteklemesine rağmen, genişletme (expansion) sözdizimini akılda tutmak zor olabilir.
Bu rehberde, Bash betiklerinde en sık kullanılan dizinli (indexed) diziler üzerinde yapılan temel işlemler detaylı olarak ele alınacaktır. Dizilerin tanımlanması, elemanlara erişim ve ilişkisel diziler hakkında daha fazla bilgi için Bash dizileri rehberine başvurabilirsiniz.
Örnek Dizi
Örneklerde aşağıdaki dizi kullanılacaktır:
fruits=( "apple" "banana" "dragon fruit" "date" "elderberry" )
Her bir tırnak içindeki değer bir eleman olarak kabul edilir ve dizinler 0'dan 4'e kadar devam eder.
Dizi Uzunluğunu Alma
Toplam Eleman Sayısını Bulma
Dizinin toplam eleman sayısını almak için ${#name[@]} genişletmesini kullanabilirsiniz:
echo "${#fruits[@]}"
Bu komut, dizideki beş eleman nedeniyle 5 çıktısını verecektir. Alternatif olarak ${#name[*]} kullanımı da aynı sonucu verir, ancak @ işaretçisi, diğer dizin işlemlerinde (örneğin dilimleme) bireysel elemanları koruduğu için daha güvenlidir.
Not:
@ve*arasındaki fark,@genişletmesinin tırnak içinde kullanıldığında her bir elemanı ayrı bir kelime olarak korumasıdır. Bu, özellikle boşluk içeren elemanlarla çalışırken önemlidir.
Tek Bir Elemanın Karakter Uzunluğunu Bulma
Belirli bir dizin konumundaki elemanın karakter uzunluğunu bulmak için, o elemanın dizinini de ekleyin:
echo "${#fruits[1]}"
Bu komut, banana kelimesinin altı karakterden oluştuğunu gösterecektir.
Dizi İçinde Değer Arama
Değerin Dizide Bulunup Bulunmadığını Kontrol Etme
Bash, dizilerde değer arama için yerleşik bir contains operatörüne sahip değildir. Güvenilir bir yaklaşım, diziyi döngüye alarak her bir elemanı hedef değerle karşılaştırmaktır:
contains() {
local target=$1
shift
local element
for element in "$@"; do
if [[ $element == "$target" ]]; then
return 0
fi
done
return 1
}
if contains "dragon fruit" "${fruits[@]}"; then
echo "found"
else
echo "not found"
fi
Bu fonksiyon, hedef değer bulunduğunda 0, bulunmadığında ise 1 durum kodunu döndürür. "${fruits[@]}" kullanımı, boşluk içeren değerleri korur.
Uyarı: Diziyi tek bir string haline getirip düzenli ifadelerle arama yapmak gibi kolay yollardan kaçının. Bu yaklaşım, arama teriminin başka bir elemanın içinde yer alması veya elemanların ayırıcı karakterler içermesi durumunda yanlış eşleşmelere neden olabilir.
Dizi Dilimleme
Diziyi Dilimleme
Dizi dilimleme için aşağıdaki genişletme kullanılır:
${name[@]:offset:length}
offset, dilimin başladığı konumu seçer ve length, döndürülecek eleman sayısını belirtir. Örneğin, dizinden 1. dizinden başlayarak üç eleman almak için:
slice=( "${fruits[@]:1:3}" )
printf '<%s>
' "${slice[@]}"
Bu komut, banana, dragon fruit ve date elemanlarını yeni bir dizi halinde döndürecektir.
Negatif Offset ile Dilimleme
Negatif bir offset kullanarak dizinin sonundan başlayabilirsiniz. Negatif sayıdan önce bir boşluk bırakarak Bash'in :- operatörünü varsayılan değer operatörü olarak algılamasını önleyin:
last_two=( "${fruits[@]: -2}" )
printf '<%s>
' "${last_two[@]}"
Bu komut, dizinin son iki elemanını (date ve elderberry) döndürecektir.
Not:
lengthparametresini belirtmediğinizde, offset konumundan dizinin sonuna kadar olan tüm elemanlar alınır.
Diziyi Ters Çevirme
Diziyi Ters Sıraya Çevirme
Bash, dizileri ters çevirmek için yerleşik bir operatöre sahip değildir. Aşağıdaki döngü, dizinin dizinlerini sondan başa doğru okuyarak her bir değeri yeni bir diziye ekler:
indices=( "${!fruits[@]}" )
reversed=()
for ((i=${#indices[@]}-1; i>=0; i--)); do
reversed+=( "${fruits[${indices[i]}]}" )
done
printf '<%s>
' "${reversed[@]}"
Bu işlem, diziyi ters çevirerek elderberry, date, dragon fruit, banana ve apple sırasını oluşturacaktır.
Not: Bu yöntem, hem sürekli dizilerde hem de dizinler arasında boşluklar bulunan seyrek dizilerde de çalışır.
Başka Araçlar:
revvetacgibi araçlar farklı problemleri çözmek için kullanılır.rev, her giriş satırındaki karakterleri ters çevirirken,tacsatır sırasını ters çevirir. Bu araçlar doğrudan Bash dizileri üzerinde çalışmaz.
Dizi Üzerinde Döngü İşlemleri
Sadece Değerler Üzerinde Döngü Yapma
Sadece dizinin değerleri üzerinde döngü yapmak için "${name[@]}" genişletmesini kullanın:
for fruit in "${fruits[@]}"; do
echo "$fruit"
done
Tırnak içindeki genişletme, dragon fruit gibi boşluk içeren değerlerin tek bir döngü öğesi olarak kalmasını sağlar.
Hem Dizin Hem De Değer Üzerinde Döngü Yapma
Hem dizin hem de değer üzerinde döngü yapmak için ${!name[@]} kullanarak dizin listesini genişletin:
for i in "${!fruits[@]}"; do
echo "$i: ${fruits[i]}"
done
Bu işlem, her bir dizin ve karşılık gelen değeri ekrana yazdırır.
Diziye Eleman Ekleme ve Önüne Ekleme
Dizinin Sonuna Eleman Ekleme
Dizinin sonuna bir veya daha fazla eleman eklemek için += operatörünü kullanın:
fruits+=( "fig" "grape" )
Yeni değerler, dizinin sonuna eklenir ve mevcut dizinlerin devamı olarak yeni dizinler alır.
Dizinin Başına Eleman Ekleme
Dizinin başına bir eleman eklemek için, yeni elemanı önce ekleyerek diziyi yeniden oluşturun:
fruits=( "apricot" "${fruits[@]}" )
Bu atama, diziyi 0'dan başlayan sürekli dizinlerle yeniden oluşturur.
Belirli Bir Dizin Konumuna Değer Atama
Belirli bir dizin konumuna değer atamak için aşağıdaki sözdizimini kullanın:
fruits[10]="kiwi"
Bu işlem, dizinler 7 ila 9 arasında boşluk bırakarak seyrek bir dizi oluşturur.
Dizi Elemanlarını Kaldırma
Belirli Bir Dizin Konumundaki Elemanı Kaldırma
Belirli bir dizin konumundaki elemanı kaldırmak için unset komutunu kullanın:
unset 'fruits[2]'
Argümanı tırnak içine alarak köşeli parantezlerin dosya adı kalıbı olarak algılanmasını önleyin. Kaldırılan dizin konumunda boşluk oluşur ve kalan elemanlar orijinal dizinlerini korur.
Diziyi Yeniden İndeksleme
Diziyi sürekli dizinlere sahip olacak şekilde yeniden oluşturmak için dizinin mevcut değerlerini kendisine atayın:
fruits=( "${fruits[@]}" )
Bu işlem, değerleri korur ve dizinleri 0'dan yeniden numaralandırır.
Tüm Diziyi Kaldırma
Tüm diziyi kaldırmak için sadece dizinin adını kullanın:
unset fruits
Hızlı Referans
| Görev | Sözdizimi |
|---|---|
| Eleman sayısı | ${#arr[@]} |
| Tek bir elemanın uzunluğu | ${#arr[index]} |
| Tüm değerler | "${arr[@]}" |
| Tüm dizinler | "${!arr[@]}" |
| Dilim | "${arr[@]:offset:length}" |
| Son iki eleman | "${arr[@]: -2}" |
| Eleman ekleme | arr+=(x y) |
| Başa eleman ekleme | arr=(x "${arr[@]}") |
| Belirli bir dizine değer atama | arr[index]=value |
| Tek bir elemanı kaldırma | unset 'arr[index]' |
| Kaldırmadan sonra yeniden indeksleme | arr=("${arr[@]}") |
| Tüm diziyi kaldırma | unset arr |
Yaygın Hatalar ve Çözümleri
-
Dizilere Erişimde Süslü Parantezleri Kullanmama:
$fruits[1]komutu,$fruitsdeğişkenini genişletir ve ardından[1]metnini ekrana yazdırır. Doğru kullanım${fruits[1]}olmalıdır. -
Dizi Genişletmelerini Tırnak İçinde Kullanırken Dikkat Etmeme:
"${fruits[@]}"kullanımı, her bir elemanı ayrı bir kelime olarak genişletirken,"${fruits[*]}"tüm elemanlarıIFSdeğişkeninin ilk karakteriyle birleştirir. Döngüler ve fonksiyonlarda@formunu kullanın. -
Dizinlerin Sürekli Olduğunu Varsayma:
unsetkullanımı veya uzak bir dizine değer atanması sonrasında dizinlerin sürekli olduğunu varsaymayın. Gerçek dizin değerleri önem taşıyorsa"${!fruits[@]}"üzerinden döngü yapın. -
Negatif Offset Kullanırken Boşluk Bırakmama:
Negatif offset kullanırken
: -operatörünü varsayılan değer operatörü olarak algılanmasını önlemek için boşluk bırakın. Örneğin:${arr[@]: -2}.
Sonuç
Bash dizilerinin uzunluklarını bulma, dilimleme, ters çevirme ve diğer temel işlemleri, genişletme mekanizmalarıyla kolayca yapılabilir. Dizi elemanlarının sınırlarını korumak için tırnak içindeki @ genişletmelerini kullanın ve dizinler arasında boşluklar olabileceğini unutmayın. Bu rehberde verilen örnekler ve açıklamalar, Bash betiklerinde dizilerle çalışırken karşılaşabileceğiniz yaygın durumlar için temel bir referans oluşturacaktır.


