1 #!/bin/bash
2 # query2.sh
3
4 numbers=(53 8 12 9 784 69 8 7 1)
5 i=4
6
7 echo ${numbers[@]} # <--- this echoes "53 8 12 9 784 69 8 7 1" to stdout.
8 echo ${numbers[i]} # <--- this echoes "784" to stdout.
9
10 unset numbers[i]
11
12 echo ${numbers[@]} # <--- this echoes "53 8 12 9 69 8 7 1" to stdout.
13 echo ${numbers[i]} # <--- stdout is blank.
Dlaczego w linii 13 stdout jest puste, biorąc pod uwagę, że tablica wydaje się być zaktualizowana, sądząc po stdout linii 12?
A zatem, co powinienem zrobić, aby uzyskać zamierzoną odpowiedź „69”?
Odpowiedzi:
unset
usuwa element. Nie przenumerowuje pozostałych elementów.Możemy użyć,
declare -p
aby zobaczyć dokładnie, co się dzieje znumbers
:Zauważ, że
numbers
nie ma już elementu4
.Inny przykład
Przestrzegać:
Tablica
a
nie ma elementów od 2 do 21. Bash nie wymaga, aby indeksy tablic były następujące po sobie.Sugerowana metoda wymuszenia numeracji indeksów
Zacznijmy od
numbers
tablicy z brakującym elementem4
:Jeśli chcielibyśmy zmienić wskaźniki, to:
Jest teraz numer elementu
4
i ma on wartość69
.Alternatywna metoda usuwania elementu i zmiany numeracji tablicy w jednym kroku
Ponownie zdefiniujmy
numbers
:Jak zasugerował Toby Speight w komentarzach, metoda usunięcia czwartego elementu i zmiany numeracji pozostałych elementów w jednym kroku:
Jak widać, czwarty element został usunięty, a wszystkie pozostałe elementy zostały ponumerowane.
${numbers[@]:0:4}
tablica plasterkównumbers
: pobiera pierwsze cztery elementy, zaczynając od elementu 0.Podobnie,
${numbers[@]:5}
pokrój tablicęnumbers
: bierze wszystkie elementy, zaczynając od elementu 5 i kontynuując do końca tablicy.Uzyskiwanie wskaźników tablicy
Te wartości tablicy można uzyskać
${a[@]}
. Aby znaleźć indeksy (lub klucze ) odpowiadające tym wartościom, użyj${!a[@]}
.Na przykład rozważmy jeszcze raz naszą tablicę
numbers
z brakującym elementem4
:Aby zobaczyć, które indeksy są przypisane:
Znowu
4
brakuje jej na liście indeksów.Dokumentacja
Od
man bash
:źródło
a=()
zmiennaa
jest nadal niezdefiniowana, dopóki nie zostanie przypisana do jednego z jej indeksów.unset numbers[4]
przypisać całą tablicę za pomocą krojenia, tj.numbers=("${numbers[@]:0:4}" "${numbers[@]:5}")
(Napisałbym jako odpowiedź, ale nie mam czasu na właściwe wyjaśnienie).bash
tablice jak wksh
, nie są tak naprawdę tablicami, są bardziej jak tablice asocjacyjne z kluczami ograniczonymi do dodatnich liczb całkowitych (lub tak zwanych tablic rzadkich ). Na powłoce z prawdziwymi tablicami, można przyjrzeć się jak muszlerc
,es
,fish
,yash
,zsh
(lub nawetcsh
/tcsh
chociaż te muszle mają tak wiele problemów oni lepiej unikać).W
zsh
:(Zauważ, że w zsh,
unset 'a[3]'
faktycznie ustawia go na pusty ciąg znaków dla lepszej kompatybilności zksh
)w
yash
:w
fish
(nie przypomina powłoki Bourne'a w przeciwieństwie dobash
/zsh
):w
es
(oparty narc
, nie podobny do Bourne'a)w
ksh
ibash
Możesz użyć tablic jako zwykłych tablic, jeśli:
po każdej operacji usuwania lub wstawiania, która mogła sprawić, że lista indeksów nie była ciągła lub nie zaczynała się od 0. Należy również pamiętać, że
ksh
/bash
tablice zaczynają się od 0, a nie 1 (z wyjątkiem$@
(pod pewnymi względami)).To w efekcie uporządkuje elementy i przeniesie je kolejno do indeksu 0, 1, 2 ...
Pamiętaj również, że musisz podać
number[i]
w:W przeciwnym razie byłoby to traktowane tak,
unset numberi
jakbynumberi
w bieżącym katalogu był plik .źródło