2016-06-14 9 views
6

In Bash möchte ich einen Eintrag einer hashmap deaktivieren. Aber ich habe versagt. Code ist wie folgt:Bash hashmap mit Zitat als Schlüssel

declare -A arr 
arr["a'b"]=3 
echo ${!arr[@]} ## output: a'b 
key="a'b" 
unset arr[$key] ## error: -bash: unset: `arr[a'b]': not a valid identifier 

Wie kann ich diesen Eintrag deaktivieren?

+0

['Unset arr [" $ Schlüssel "]'] (http://mywiki.wooledge.org/BashGuide/Practices#Quoting)? ** EDIT **: Das funktioniert auch nicht ... – anishsane

+1

Sieht aus wie ein Fehler in Bash – Leon

+0

Hmm ... meine schlechte ... Auch, 'arr ['$ x'] = 123; unset arr ['$ x'] 'gibt '-bash: unset: [$ x]: schlechtes Array tiefgestellt' – anishsane

Antwort

5

Nur einfache Anführungszeichen:

$ declare -A arr=(["a'b"]=3 [foo]=bar) 
$ declare -p arr 
declare -A arr='(["a'\''b"]="3" [foo]="bar")' 
$ key="a'b" 
$ unset 'arr[$key]' 
$ declare -p arr 
declare -A arr='([foo]="bar")' 

Fertig!

+0

brilliant way! – ruanhao

+1

Das ist magisch. Ist dokumentiert, dass "unset" eine zweite Erweiterungsrunde durchführt? –

+0

@glennjackman: Ich habe es nicht wirklich dokumentiert gesehen, aber es ist nicht spezifisch für "unset". Der arithmetische Kontext zeigt auch dieses Verhalten: 'declare -A glenn; key = '$ (ls> &2)'; ((glenn [$ key])) '. Überraschung. Die Antwort ist wahrscheinlich in der Quelle':) '. Bash hat eine wirklich verrückte Art, Dinge zu analysieren. –

4

Tricky. Sie können es manuell tun, indem Sie das "innere" einfache Angebot umgehen:

$ declare -A arr=(["a'b"]=3 [foo]=bar) 
$ key="a'b" 
$ unset "arr[$key]" 
bash: unset: `arr[a'b]': not a valid identifier 
$ unset "arr[a\'b]" 
$ declare -p arr 
declare -A arr='([foo]="bar")' 

Aber wie man es "programmatisch" macht? Zum Glück hat bash einen Mechanismus zu "entkommen" einen String: printf "%q":

$ declare -A arr=(["a'b"]=3 [foo]=bar) 
$ echo "$key" 
a'b 
$ printf "%q" "$key" 
a\'b 
$ unset "arr[$(printf "%q" "$key")]" 
$ declare -p arr 
declare -A arr='([foo]="bar")' 
Verwandte Themen