Bash'te dizini belirtmeden diziye yeni bir öğe ekleme


Yanıtlar:


1540

Evet var:

ARRAY=()
ARRAY+=('foo')
ARRAY+=('bar')

Bash Referans Kılavuzu :

Atama ifadesinin kabuk değişkenine veya dizi dizinine bir değer atadığı bağlamda (bkz. Diziler), '+ =' operatörü değişkenin önceki değerine eklemek veya bu değere eklemek için kullanılabilir.


21
Bu, bash 3.2.48 (OS X 10.8.2) ile gayet iyi çalışıyor. Bunun ARRAYyalnızca gerçek bir değişken adı için bir yer tutucu olduğunu unutmayın . Diziniz endeksleri bile değil sıralı ile ekleme +=sadece en yüksek endeks + 1 atayacağı
mklement0

3
Bash 4.2.24 (1) sürümünde böyle bir şey var mı?
Ali Ismayilov

195
ARRAY + = ('foo') 'nun en düşük (?) Anahtarlı girişe' foo 'dizesini ekleyen ARRAY + =' foo 'dan çok farklı olduğunu belirtmek önemlidir.
Yapımcı

8
Wiki.bash-hackers.org/scripting/bashchanges'e göre , bu sözdizimi ilk önce 3.1-alfa1 sürümünde yer aldı.
David Yaw

39
@Jas: Tüm diziye erişmek için şunu kullanmalısınız ${myarray[@]}- bir dizi değişkenine skalermiş gibi başvurmak , öğesinin 0 değerine erişmekle aynıdır; diğer bir deyişle: $myarrayile aynıdır ${myarray[0]}.
mklement0

76

Dumb Guy'ın belirttiği gibi , dizinin sıfırdan başlayıp sıralı olup olmadığını not etmek önemlidir. Bitişik olmayan indekslere atama yapabileceğiniz ve bu dizinleri kaldırabileceğiniz için ${#array[@]}dizinin sonundaki her zaman bir sonraki öğe değildir.

$ array=(a b c d e f g h)
$ array[42]="i"
$ unset array[2]
$ unset array[3]
$ declare -p array     # dump the array so we can see what it contains
declare -a array='([0]="a" [1]="b" [4]="e" [5]="f" [6]="g" [7]="h" [42]="i")'
$ echo ${#array[@]}
7
$ echo ${array[${#array[@]}]}
h

Son dizini nasıl alacağınız aşağıda açıklanmıştır:

$ end=(${!array[@]})   # put all the indices in an array
$ end=${end[@]: -1}    # get the last one
$ echo $end
42

Bu, bir dizinin son elemanının nasıl alınacağını gösterir. Bunu sıklıkla göreceksiniz:

$ echo ${array[${#array[@]} - 1]}
g

Gördüğünüz gibi, seyrek bir dizi ile uğraştığımız için, bu son öğe değil. Bu hem seyrek hem de bitişik dizilerde çalışır:

$ echo ${array[@]: -1}
i

3
Harika şeyler; alt dizeleri çıkarma sözdiziminin dizilere de uygulanabileceğini asla bilmiyordu; deneme yanılma ile belirlenen kurallar şunlardır (bash 3.2.48): ${array[@]: start[:count]}İade sayılarını döndürür. veya belirtilmezse, kalan tüm öğeler. başlayarak aşağıdaki elem .: - Eğer başlangıç> = 0: elem. dizini> = başlangıç ​​olan. - Eğer başlangıç ​​<0 ise: elemden. dizini (son dizi dizini + 1) - abs (başlat); CAVEAT: abs (start)> (son dizi dizini + 1) ise, boş bir dize döndürülür. Sayı belirtilirse, indeksleri başlangıçtan bitişik olmasa bile, birçok öğe döndürülür.
mklement0

3
@mklement: Bash 4.2'de, dizinin sonundan itibaren sayılan öğelere erişmek için negatif dizi aboneliklerini kullanabilirsiniz. ${array[-1]}
sonraki duyuruya kadar duraklatıldı.

Bunu bilmek güzel, teşekkürler. OS X (10.8.2'den itibaren) hala 3.2.48 kullanıyor ve stackoverflow.com/questions/10418616/… bana maalesef "Apple lisanslı kod göndermediği için Bash'in oldukça eski bir sürümünü kullanıyor GPL3 altında. "
mklement0

49
$ declare -a arr
$ arr=("a")
$ arr=("${arr[@]}" "new")
$ echo ${arr[@]}
a new
$ arr=("${arr[@]}" "newest")
$ echo ${arr[@]}
a new newest

8
e-t172 ile açıklanan + = operatörünün anlamını desteklemeyen bash sürümleri için güzel
akostadinov

12
iyi bir geriye dönük uyumlu çözüm, ancak mevcut öğelerin herhangi birinde boşluk varsa, bunların birden çok öğeye bölüneceğine dikkat edin; arr=("${arr[@]}" "new")içinde boşluk bulunan elemanlarınız varsa kullanın
kbolino

1
Bu aynı zamanda sadece ihtiyacım olan dizi önünde itmek için kullanılabilir.
Tomáš Zato - Monica'yı eski durumuna getir

29

Diziniz her zaman ardışıksa ve 0'dan başlıyorsa, bunu yapabilirsiniz:

array[${#array[@]}]='foo'

# gets the length of the array
${#array_name[@]}

Yanlışlıkla eşittir işareti arasındaki boşlukları kullanırsanız:

array[${#array[@]}] = 'foo'

Ardından aşağıdakine benzer bir hata alırsınız:

array_name[3]: command not found

5
Evet, ancak +=sözdizimi (bkz. @ E-t172'nin cevabı) (a) daha basittir ve (b) bitişik olmayan ve / veya 0 ile başlamayan dizilerle de çalışır.
mklement0

Dürüst olmak gerekirse bu çözüm (benim için) "+ =" den daha iyi çalışıyor, çünkü ikincisi ile uzunluk bazen yanlıştır (bir öğe eklerken iki kat artar) ... bu yüzden bu yanıtı tercih ederim! :)
Pierpaolo Cira

Bu aynı zamanda +=
bash'ın

1
Bu, öğelerinizde boşluklar olduğunda da çalışır - $arr += ($el)dizeyi uzaya bölüyor ve öğelerin her birini ekliyor gibiydi.
Maksimum

5

Dizine alınmış bir dizi ile aşağıdakine benzer bir şey yapabilirsiniz:

declare -a a=()
a+=('foo' 'bar')
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.