Ich versuche, den Bereich des Array-Elements zu löschen, aber es schlägt fehl.
Mein Array
root@ubuntu:~/work# echo ${a[@]}
cocacola.com airtel.com pepsi.com
Das Drucken des 0-1-Arrays sieht ok aus
root@ubuntu:~/work# echo ${a[@]::2}
cocacola.com airtel.com
Jetzt versuche ich, nur diese Elemente zu löschen, indem ich Folgendes verwende:
root@ubuntu:~/work# unset a[@]::2
root@ubuntu:~/work# echo ${a[@]}
Es löscht das ganze Array.
Was mache ich falsch?
Ich habe eine andere Möglichkeit gefunden, den Array-Bereich zu löschen, aber warum funktioniert das oben Genannte nicht?
for ((i=0; i<2; i++)); do unset a[$i]; done
EDIT Ich hatte es auch versucht, aber kein Glück
unset -v 'a[@]::2'
Antwort1
Zu bedenken ist, dass bash
Arrays wie ksh
als assoziative Arrays implementiert sind, bei denen die Schlüssel auf positive Ganzzahlen beschränkt sind (im Gegensatz zu anderen Sprachen wie beispielsweise perl
oder ).zsh
In:
a[123]=foo a[456]=bar a[789]=baz
In Bash haben Sie ein assoziatives Array mit 3 Elementen, während perl
Sie in ein Array mit 790 Elementen hätten (789 mit Zsh).
Gibt in ksh
oder das erste Element des Arrays in der Liste der Elemente zurück, die numerisch nach Schlüssel sortiert sind, wobei der Schlüssel größer oder gleich 0 ist. In diesem Fall wird also zurückgegeben , nicht .bash
${a[@]:0:1}
${a[123]}
${a[0]}
unset 'a[123]'
(denken Sie daran, es in Anführungszeichen zu setzen, sonst würde es fehlschlagen, wenn sich im aktuellen Verzeichnis eine Datei mit dem Namen a1 oder a2 oder a3 befände) ist sinnvoll, da dadurch ein bestimmter Schlüssel im Array entfernt wird.
unset 'a[@]::2'
ergibt allerdings weniger Sinn. bash
versteht nur unset a
, unset 'a[123]'
oder unset 'a[*/@]'
, alles danach wird ignoriert, also machen Sie unset 'a[@]::2'
und unset 'a[@]please'
dasselbe: Setzen Sie das gesamte Array zurück.
Wenn Sie einen Schlüsselbereich aufheben möchten, müssen Sie eine Schleife durch die Schlüssel ausführen:
Um die Liste der Schlüssel des Arrays zu erhalten, lautet die Syntax "${!a[@]}"
. Leider funktioniert das Anwenden eines Bereichs darauf nicht mit bash
nor ksh
, daher benötigen Sie ein temporäres Array:
keys=("${!a[@]}")
for i in "${keys[@]::2}"; do unset "a[$i]"; done
Wenn Sie diese Arrays nun wie in anderen Sprachen betrachten möchten, sollten Sie nicht verwenden unset
. Wenn das Array beispielsweise von vornherein nicht spärlich besetzt ist und Sie dies beibehalten möchten (das heißt alle Elemente um 2 verschieben, anstatt die ersten beiden zu löschen), können Sie Folgendes tun:
a=("${a[@]:2}")
Das heißt, weisen Sie dem Array die Liste der Elemente neu zu, die Sie behalten möchten.
Zum Vergleich mit zsh
.
a=({1..20})
unset 'a[12,16]'
würde einen leeren Wert auf die Elemente 12 bis 16 setzen, während unset 'a[16,20]'
das Array auf 15 Elemente verkleinert würde.
a=({1..20})
a[12,16]=()
(immer noch mit zsh
) würde die Elemente 17 bis 20 um 5 Positionen verschieben, a[12]
würde also enthalten 17
.
Antwort2
Wenn Ihr Arraykontinuierlich/nicht spärlich(alle Elemente aus dem Satz 0..N-1)
Sie können das 2. Element des Arrays entfernen mit
unset 'a[1]'
Um das 2., 3. und 4. Element zu entfernen, können Sie beispielsweise verwenden
for ((i=1; i<=3; i++)); do unset "a[$i]"; done
Um alle Elemente außer dem 1. und 2. zu löschen, können Sie beispielsweise verwenden
for ((i=2; i<${#a[@]}; i++)); do unset "a[$i]"; done
Allgemeine Lösung(funktioniert auch für dünn besetzte Arrays): Sie können das 2. Element des Arrays entfernen mit
unset "a[$(echo ${!a[@]} | cut -d" " -f 2)]"
Um das 2., 3. und 4. Element zu entfernen, können Sie beispielsweise verwenden
for $(echo ${!a[@]} | cut -d" " -f 2-4) ; do unset "a[$i]"; done
Um alle Elemente außer dem 1. und 2. zu löschen, können Sie beispielsweise verwenden
for $(echo ${!a[@]} | cut -d" " -f 2-) ; do unset "a[$i]"; done