2016-06-14 70 views
6

在Bash中,我想取消设置hashmap的条目。但我失败了。代码如下:使用引号作为键的Bash hashmap

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 

如何取消设置此条目?

+0

['unset arr [“$ key”]'](http://mywiki.wooledge.org/BashGuide/Practices#Quoting)? **编辑**:这也不起作用... – anishsane

+1

看起来像在bash中的错误 – Leon

+0

嗯......我的坏......另外,'arr ['$ x'] = 123; unset arr ['$ x']'给出'-bash:unset:[$ x]:bad array subscript' – anishsane

回答

5

只需使用单引号:

$ 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")' 

完成!

+0

辉煌的样子! – ruanhao

+1

这是神奇的。是否记录了'unset'进行第二轮扩展? –

+0

@glennjackman:我还没有看到它的记录,真的,但它不是特定于'unset'。算术上下文也显示了这种行为:'declare -A glenn; key ='$(ls> &2)';((glenn [$ key]))'。惊喜。答案可能在源代码':)'中。 Bash有一种非常疯狂的解析方式。 –

4

棘手。您可以通过转义“内部”单引号来手工完成:

$ 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")' 

但是如何“编程”呢?幸运的bash确实有一个机制,以 “逃脱” 的字符串: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")'