Tambahkan elemen baru ke array tanpa menentukan indeks di Bash

Jawaban:

1540

Ya ada:

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

Manual Referensi Bash :

Dalam konteks di mana pernyataan penugasan memberikan nilai ke variabel shell atau indeks array (lihat Array), operator '+ =' dapat digunakan untuk menambahkan atau menambah nilai variabel sebelumnya.

Etienne Dechamps
sumber
21
Ini berfungsi dengan baik dengan bash 3.2.48 (OS X 10.8.2). Perhatikan bahwa ARRAYini hanyalah pengganti untuk nama variabel aktual. Bahkan jika indeks array Anda tidak berurutan, menambahkan dengan +=hanya akan menetapkan indeks tertinggi + 1.
mklement0
3
Apakah ada sesuatu seperti itu di bash versi 4.2.24 (1)?
Ali Ismayilov
195
Penting untuk dicatat, bahwa ARRAY + = ('foo') jauh berbeda dari ARRAY + = 'foo', yang menambahkan string 'foo' ke entri dengan kunci terendah (?).
TheConstructor
8
Menurut wiki.bash-hackers.org/scripting/bashchanges , sintaks ini pertama kali muncul di versi 3.1-alpha1.
David Yaw
39
@Jas: Untuk mengakses seluruh array, Anda harus menggunakan ${myarray[@]}- mereferensikan variabel array seolah-olah skalar sama dengan mengakses elemennya 0; dengan kata lain: $myarraysama dengan ${myarray[0]}.
mklement0
76

Seperti yang ditunjukkan oleh Dumb Guy , penting untuk dicatat apakah array dimulai dari nol dan berurutan. Karena Anda dapat membuat penugasan ke dan menghapus indeks ${#array[@]}yang tidak bersebelahan tidak selalu menjadi item berikutnya di akhir array.

$ 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

Berikut cara mendapatkan indeks terakhir:

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

Itu menggambarkan cara mendapatkan elemen terakhir dari array. Anda akan sering melihat ini:

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

Seperti yang Anda lihat, karena kita berurusan dengan array yang jarang, ini bukan elemen terakhir. Ini berfungsi pada array yang jarang dan berdekatan, meskipun:

$ echo ${array[@]: -1}
i
Dijeda sampai pemberitahuan lebih lanjut.
sumber
3
Hal-hal besar; tidak pernah tahu bahwa sintaksis substring-ekstraksi dapat diterapkan ke array juga; aturan, ditentukan oleh coba-coba, adalah (bash 3.2.48): ${array[@]: start[:count]}Pengembalian jumlah elem. atau, jika tidak ditentukan, semua elem yang tersisa . mulai dari elem berikut .: - Jika mulai> = 0: dari elem. indeks siapa>> mulai. - Jika mulai <0: dari elem. yang indeksnya (indeks array terakhir + 1) - abs (mulai); CAVEAT: jika abs (mulai)> (indeks array terakhir + 1), string null dikembalikan. Jika jumlah ditentukan, karena banyak elemen dikembalikan, bahkan jika indeks mereka tidak berdekatan dari awal.
mklement0
3
@mklement: Di Bash 4.2, Anda bisa menggunakan larik larik negatif untuk mengakses elemen yang dihitung dari akhir larik. ${array[-1]}
Dijeda sampai pemberitahuan lebih lanjut.
Itu bagus untuk diketahui, terima kasih. OS X (pada 10.8.2) masih menggunakan 3.2.48, dan stackoverflow.com/questions/10418616/… mengatakan kepada saya bahwa, sayangnya, "Apple menggunakan versi Bash yang cukup lama, karena mereka tidak mengirimkan kode yang dilisensikan di bawah GPL3. "
mklement0
49
$ declare -a arr
$ arr=("a")
$ arr=("${arr[@]}" "new")
$ echo ${arr[@]}
a new
$ arr=("${arr[@]}" "newest")
$ echo ${arr[@]}
a new newest
ghostdog74
sumber
8
bagus untuk versi bash yang tidak mendukung semantik + = operator yang dijelaskan oleh e-t172
akostadinov
12
solusi kompatibel-mundur yang baik, tetapi berhati-hatilah bahwa jika ada elemen yang ada yang memiliki ruang di dalamnya, mereka akan dipecah menjadi beberapa elemen; gunakan arr=("${arr[@]}" "new")jika Anda memiliki elemen dengan spasi di dalamnya
kbolino
1
Ini juga dapat digunakan untuk mendorong di depan array, yang memang saya butuhkan.
Tomáš Zato - Kembalikan Monica
29

Jika array Anda selalu berurutan dan dimulai dari 0, maka Anda bisa melakukan ini:

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

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

Jika Anda secara tidak sengaja menggunakan spasi di antara tanda sama dengan:

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

Maka Anda akan menerima kesalahan yang mirip dengan:

array_name[3]: command not found
Cowok Bisu
sumber
5
Ya, Anda bisa, tetapi +=sintaksnya (lihat jawaban @ e-t172) adalah (a) lebih sederhana, dan (b) juga bekerja dengan array yang tidak bersebelahan dan / atau tidak memulai dengan 0.
mklement0
Jujur solusi ini (untuk saya) bekerja lebih baik daripada "+ =", karena dengan yang terakhir panjangnya kadang-kadang salah (bertambah dua ketika menambahkan satu elemen) ... jadi saya lebih suka balasan ini! :)
Pierpaolo Cira
Ini juga berfungsi di versi bash sebelumnya, sebelum +=ditambahkan, mis. Versi 2
Zoey Hewll
1
Ini juga berfungsi ketika elemen Anda memiliki spasi di dalamnya - $arr += ($el)tampak membelah string dengan spasi dan menambahkan masing-masing elemen.
Maks
5

Dengan array yang diindeks, Anda dapat melakukan sesuatu seperti ini:

declare -a a=()
a+=('foo' 'bar')
Grégory Roche
sumber