当键包含引号时,在关联的bash数组中取消值

时间:2016-08-26 18:14:26

标签: arrays bash escaping associative-array

我有一个bash脚本,它使用文件名作为关联数组中的键。一些文件名中有引号,我似乎无法找到任何方法来取消它们。

以下是从终端复制问题的示例:

$ declare -A x
$ y="key with spaces"
$ z="key with spaces and ' quote"
$ x[$y]=5   # this works fine
$ x[$z]=44  # as does this
$ echo "${x[$y]}" "${x[$z]}" # no problems here
5 44
$ unset x["$y"] # works
$ unset x["$z"] # does not work
bash: unset: `x[key with spaces and ' quote]': not a valid identifier
$ echo "${x[$y]}" "${x[$z]}" # second key was not deleted
 44

在我的脚本中处理的文件名是任意的,无论它们在哪些字符中都需要工作(在合理范围内,至少需要使用可打印的字符。)unset用于清除文件上的标记属性。

如果这些特定键可能包含引号,我怎样才能让bash取消设置?

3 个答案:

答案 0 :(得分:2)

我发现这对我有用:

unset 'x[$z]'

这适用于其他特殊字符:

$ y="key with spaces"
$ v="\$ ' \" @ # * & \`"
$ x[$y]=5
$ x[$v]=10
$ echo ${x[*]}
5 10
$ unset 'x[$v]'
$ echo ${x[*]}
5

答案 1 :(得分:2)

这种情况下,关联数组键周围的单引号也起作用,所以这应该有效:

$> declare -p x
declare -A x='(["key with spaces and '\'' quote"]="44" )'

$> unset x['$z']

$> declare -p x
declare -A x='()'

答案 2 :(得分:1)

这可能是一个错误(至少,它是不方便的)。在修复程序可用之前,您可以通过使用

获取$z的shell引用版本来解决此问题。
$ unset x["$(printf '%q' "$z")"]

bash 4.4中,可以更简单地将其写为

$ unset x["${z@Q}"]