2016-06-14 3 views
6

Bashでは、ハッシュマップのエントリの設定を解除します。しかし、私は失敗しました。コードは次のとおりです。引用符をキーとして使用するBashハッシュマップ

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]:不正な配列の添え字 ' – anishsane

答えて

5

ちょうど単一引用符を使用します!

+0

は素晴らしい方法です! – ruanhao

+1

それは魔法です。 'unset'が2回目の展開をしていることが文書化されていますか? –

+0

@glennjackman:私はそれが本当に文書化されているのを見たことはありませんが、それは 'unset'に特有のものではありません。算術コンテキストもこの動作を示します: 'declare -A glenn; $(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) 
$ 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")' 

が完了:

$ 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")' 
関連する問題