我有一个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取消设置?
答案 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}"]