Hier ist eine (wahrscheinlich sehr bash-spezifische) kleine Funktion, die die Indirektion von Bash-Variablen beinhaltet und unset
; Es handelt sich um eine allgemeine Lösung, bei der kein Text ersetzt oder leere Elemente verworfen werden und keine Probleme mit Anführungszeichen / Leerzeichen usw. auftreten.
delete_ary_elmt() {
local word=$1 # the element to search for & delete
local aryref="$2[@]" # a necessary step since '${!$2[@]}' is a syntax error
local arycopy=("${!aryref}") # create a copy of the input array
local status=1
for (( i = ${#arycopy[@]} - 1; i >= 0; i-- )); do # iterate over indices backwards
elmt=${arycopy[$i]}
[[ $elmt == $word ]] && unset "$2[$i]" && status=0 # unset matching elmts in orig. ary
done
return $status # return 0 if something was deleted; 1 if not
}
array=(a 0 0 b 0 0 0 c 0 d e 0 0 0)
delete_ary_elmt 0 array
for e in "${array[@]}"; do
echo "$e"
done
# prints "a" "b" "c" "d" in lines
Verwenden Sie es wie delete_ary_elmt ELEMENT ARRAYNAME
ohne $
Siegel. Schalten Sie das == $word
für == $word*
für Präfix-Übereinstimmungen; Verwendung ${elmt,,} == ${word,,}
für Übereinstimmungen ohne Berücksichtigung der Groß- und Kleinschreibung; usw., was auch immer Bash [[
unterstützt.
Dabei werden die Indizes des Eingabearrays ermittelt und rückwärts durchlaufen (das Löschen von Elementen führt also nicht zu einer Verschiebung der Iterationsreihenfolge). Um die Indizes zu erhalten, müssen Sie nach Namen auf das Eingabearray zugreifen. Dies kann über die Indirektion von Bash-Variablen erfolgen x=1; varname=x; echo ${!varname} # prints "1"
.
Sie können nicht namentlich auf Arrays zugreifen aryname=a; echo "${$aryname[@]}
, dies gibt Ihnen einen Fehler. Sie können nicht tun aryname=a; echo "${!aryname[@]}"
, dies gibt Ihnen die Indizes der Variablenaryname
(obwohl es sich nicht um ein Array handelt). Was funktioniert, ist aryref="a[@]"; echo "${!aryref}"
, dass die Elemente des Arrays gedruckt werden a
, wobei Shell-Word-Anführungszeichen und Leerzeichen genau wie erhalten bleiben echo "${a[@]}"
. Dies funktioniert jedoch nur zum Drucken der Elemente eines Arrays, nicht zum Drucken seiner Länge oder Indizes ( aryref="!a[@]"
oder aryref="#a[@]"
oder "${!!aryref}"
oder"${#!aryref}"
, alle schlagen fehl).
Also kopiere ich das ursprüngliche Array durch seinen Namen per Bash-Indirektion und erhalte die Indizes aus der Kopie. Um die Indizes in umgekehrter Reihenfolge zu durchlaufen, verwende ich eine for-Schleife im C-Stil. Ich könnte es auch tun, indem ich über auf die Indizes zugreife ${!arycopy[@]}
und sie umkehre tac
, was eine Umkehrung cat
der Eingabezeilenreihenfolge ist.
Eine Funktionslösung ohne variable Indirektion müsste wahrscheinlich beinhalten eval
, was in dieser Situation sicher sein kann oder nicht (ich kann es nicht sagen).
zsh
.