Dodaj nowy element do tablicy bez określania indeksu w Bash


Odpowiedzi:


1539

Tak jest:

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

Podręcznik referencyjny Bash :

W kontekście, w którym instrukcja przypisania przypisuje wartość do zmiennej powłoki lub indeksu tablicy (patrz Tablice), operator „+ =” może być użyty do dołączenia lub dodania do poprzedniej wartości zmiennej.


21
Działa to dobrze z bash 3.2.48 (OS X 10.8.2). Zauważ, że ARRAYjest to tylko symbol zastępczy rzeczywistej nazwy zmiennej. Nawet jeśli indeksy tablicowe nie są sekwencyjne, dołączenie za pomocą +=spowoduje przypisanie do najwyższego indeksu + 1.
mklement0

3
Czy jest coś takiego w wersji bash 4.2.24 (1)?
Ali Ismayilov,

195
Należy zauważyć, że ARRAY + = („foo”) różni się znacznie od ARRAY + = „foo”, która dołącza ciąg „foo” do wpisu z najniższym klawiszem (?).
TheConstructor

8
Według wiki.bash-hackers.org/scripting/bashchanges ta składnia pojawiła się po raz pierwszy w wersji 3.1-alpha1.
David Yaw

39
@Jas: Aby uzyskać dostęp do całej tablicy, musisz użyć ${myarray[@]}- odwołanie do zmiennej tablicowej, tak jakby to był skalar, jest tym samym, co dostęp do jej elementu 0; innymi słowy: $myarrayjest taki sam jak ${myarray[0]}.
mklement0

76

Jak zauważa Dumb Guy , ważne jest, aby pamiętać, że tablica zaczyna się od zera i jest sekwencyjna. Ponieważ można przypisywać i usuwać nieciągłe indeksy, ${#array[@]}nie zawsze jest to następny element na końcu tablicy.

$ 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

Oto jak uzyskać ostatni indeks:

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

To ilustruje, jak uzyskać ostatni element tablicy. Często zobaczysz to:

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

Jak widać, ponieważ mamy do czynienia z rzadką tablicą, nie jest to ostatni element. Działa to zarówno na tablicach rzadkich, jak i przyległych:

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

3
Świetne rzeczy; nigdy nie wiedziałem, że składnia ekstrakcji substringów może być stosowana również do tablic; zasady określone metodą prób i błędów są następujące (bash 3.2.48): ${array[@]: start[:count]}Zwraca liczbę elementów. lub, jeśli nie określono, wszystkie pozostałe elementy. zaczynając od następującego elementu: - Jeśli start> = 0: od elementu. którego indeks wynosi> = start. - Jeśli start <0: od elem. którego indeks to (ostatni indeks tablicy + 1) - abs (start); CAVEAT: jeśli abs (start)> (ostatni indeks tablicy + 1), zwracany jest ciąg pusty. Jeśli podano count, zwracanych jest wiele elementów, nawet jeśli ich indeksy nie są ciągłe od początku.
mklement0

3
@mklement: W Bash 4.2 możesz użyć ujemnych indeksów tablic, aby uzyskać dostęp do elementów liczących od końca tablicy. ${array[-1]}
Wstrzymano do odwołania.

Dobrze wiedzieć, dzięki. OS X (od 10.8.2) nadal używa wersji 3.2.48, a stackoverflow.com/questions/10418616/... mówi mi, że niestety „Apple używa dość starej wersji Bash, ponieważ nie wysyłają kodu, który jest licencjonowany na licencji GPL3 ”.
mklement0

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

8
dobre dla wersji bash, które nie obsługują semantyki operatora + = wyjaśnionego przez e-t172
akostadinov

12
dobre rozwiązanie kompatybilne wstecz, ale uważaj, że jeśli którykolwiek z istniejących elementów zawiera spacje, zostaną one podzielone na wiele elementów; użyj, arr=("${arr[@]}" "new")jeśli masz elementy ze spacjami
kbolino

1
Można to również wykorzystać do wypchnięcia przed tablicę, czego właśnie potrzebuję.
Tomáš Zato - Przywróć Monikę

29

Jeśli tablica jest zawsze sekwencyjna i zaczyna się od 0, możesz to zrobić:

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

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

Jeśli przypadkowo użyjesz spacji między znakiem równości:

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

Następnie pojawi się błąd podobny do:

array_name[3]: command not found

5
Tak, ale +=składnia (patrz odpowiedź @ e-t172) jest (a) prostsza i (b) działa również z tablicami, które nie są ciągłe i / lub nie zaczynają się od 0.
mklement0

Szczerze mówiąc, to rozwiązanie (dla mnie) działa lepiej niż „+ =”, ponieważ w tym drugim przypadku długość jest czasem niepoprawna (zwiększa się o dwa przy dodawaniu jednego elementu) ... więc wolę tę odpowiedź! :)
Pierpaolo Cira,

Działa to również we wcześniejszych wersjach bash, zanim +=została dodana, np. Wersja 2
Zoey Hewll

1
Działa to również wtedy, gdy twoje elementy mają spacje - $arr += ($el)wydawało się, że dzieli ciąg znaków przez spację i dodaje każdy z elementów.
Maks.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.