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.
Warum ist in Zeile 13 das stdout leer, wenn man bedenkt, dass das Array nach dem stdout in Zeile 12 aktualisiert worden zu sein scheint?
Und was soll ich tun, um die beabsichtigte Antwort "69" zu erhalten?
Antworten:
unset
entfernt ein Element. Die verbleibenden Elemente werden nicht neu nummeriert.Wir können verwenden
declare -p
, um genau zu sehen, was passiert mitnumbers
:Beachten Sie, dass das
numbers
kein Element mehr hat4
.Ein anderes Beispiel
Beobachten:
Array
a
hat keine Elemente 2 bis 21. Bash erfordert nicht, dass Array-Indizes aufeinanderfolgend sind.Vorgeschlagene Methode, um eine Umnummerierung der Indizes zu erzwingen
Beginnen wir mit dem
numbers
Array mit dem fehlenden Element4
:Wenn wir möchten, dass sich die Indizes ändern, dann:
Es gibt jetzt eine Elementnummer
4
und sie hat einen Wert69
.Alternative Methode zum Entfernen eines Elements und zum Umnummerieren des Arrays in einem Schritt
Lassen Sie uns noch einmal definieren
numbers
:Wie von Toby Speight in den Kommentaren vorgeschlagen, eine Methode zum Entfernen des vierten Elements und zum Umnummerieren der verbleibenden Elemente in einem Schritt:
Wie Sie sehen können, wurde das vierte Element entfernt und alle verbleibenden Elemente wurden neu nummeriert.
${numbers[@]:0:4}
Slices-Arraynumbers
: Es werden die ersten vier Elemente beginnend mit Element 0 verwendet.In ähnlicher Weise
${numbers[@]:5}
Slice-Arraynumbers
: Es werden alle Elemente verwendet, die mit Element 5 beginnen und bis zum Ende des Arrays reichen.Abrufen der Indizes eines Arrays
Die Werte eines Arrays können mit erhalten werden
${a[@]}
. Verwenden Sie, um die Indizes (oder Schlüssel ) zu finden, die diesen Werten entsprechen${!a[@]}
.Betrachten Sie zum Beispiel noch einmal unser Array
numbers
mit dem fehlenden Element4
:So sehen Sie, welche Indizes zugewiesen sind:
Auch
4
hier fehlt in der Liste der Indizes.Dokumentation
Von
man bash
:quelle
a=()
die Variable nach dem Schreibena
immer noch undefiniert, bis Sie sie tatsächlich einem ihrer Indizes zuweisen.unset numbers[4]
das gesamte Array mithilfe von Slicing zu, dhnumbers=("${numbers[@]:0:4}" "${numbers[@]:5}")
(ich würde als Antwort posten, habe aber keine Zeit, dies richtig zu erklären).bash
Arrays wie inksh
sind keine wirklichen Arrays, sondern eher assoziative Arrays mit Schlüsseln, die auf positive ganze Zahlen (oder sogenannte Sparse-Arrays ) beschränkt sind. Für eine Schale mit echten Arrays Sie einen Blick auf Shells wie haben kannrc
,es
,fish
,yash
,zsh
(oder sogarcsh
/tcsh
obwohl diese Granaten so viele Probleme haben , sind sie besser vermieden).In
zsh
:(Beachten Sie, dass in zsh
unset 'a[3]'
tatsächlich eine leere Zeichenfolge festgelegt wird, um die Kompatibilität mit zu verbessern.ksh
)in
yash
:in
fish
(keine Bourne-ähnliche Hülle im Gegensatz zubash
/zsh
):in
es
(basierend aufrc
, nicht Bourne-ähnlich)in
ksh
undbash
Sie können die Arrays als normale Arrays verwenden, wenn Sie Folgendes tun:
Nach jedem Löschen oder Einfügen von Vorgängen, bei denen die Liste der Indizes möglicherweise nicht zusammenhängend ist oder nicht bei 0 beginnt. Beachten Sie auch, dass
ksh
/bash
arrays bei 0 und nicht bei 1 beginnen (außer$@
(in gewisser Weise)).Dadurch werden die Elemente aufgeräumt und nacheinander in den Index 0, 1, 2 ... verschoben.
Beachten Sie auch, dass Sie Folgendes angeben müssen
number[i]
:Andernfalls würde dies so behandelt, als ob im aktuellen Verzeichnis
unset numberi
eine Datei aufgerufennumberi
worden wäre.quelle