So heben Sie den Array-Bereich in Bash auf

So heben Sie den Array-Bereich in Bash auf

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 bashArrays wie kshals assoziative Arrays implementiert sind, bei denen die Schlüssel auf positive Ganzzahlen beschränkt sind (im Gegensatz zu anderen Sprachen wie beispielsweise perloder ).zsh

In:

a[123]=foo a[456]=bar a[789]=baz

In Bash haben Sie ein assoziatives Array mit 3 Elementen, während perlSie in ein Array mit 790 Elementen hätten (789 mit Zsh).

Gibt in kshoder 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. bashversteht 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 bashnor 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

  1. 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
    
  2. 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
    

verwandte Informationen