Bad array subscript error when trying to increment an associative array element

这一生的挚爱 提交于 2020-07-29 14:28:57

问题


I can create an associative array and assign an integer to a key that contains a single quote in it:

$ declare -A dict
$ var="john's"
$ dict[$var]=1
$ echo ${dict[$var]}
1
$ declare -p dict
declare -A dict=(["john's"]="1" )

But when I try to increment its value:

$ (( dict[$var]++ ))
bash: ((: dict[john's]++ : bad array subscript (error token is "dict[john's]++ ")
$ (( dict["$var"]++ ))
bash: ((: dict[john's]++ : bad array subscript (error token is "dict[john's]++ ")
$ (( dict["${var}"]++ ))
bash: ((: dict[john's]++ : bad array subscript (error token is "dict[john's]++ ")

I always get the same error. What am I doing wrong?


回答1:


The single quote in key name is causing the parser to treat it as a un-terminated quote character. One way to fix this would be to escape the ' character in the key

key="john's"
printf -v escKey "%q" "$key"

now because of the %q specifier, printf() would have applied required escapes to all shell meta characters i.e. making it "shell-quoted" and re-usable. If you print the contents of escKey you'll notice the ' escaped

printf '%s\n' "$escKey"
john\'s

Now you can use this keyname in your associative array. Remember you can always manually add the escapes which could be messy. Since %q is a native way provided by the shell, it is much safe to use it.

(( dict["$escKey"]++ ))

Also in bash versions >= 4.4 parameter expansion has @Q which is a shortcut for %q specifier of printf() using which you can do

(( dict["${key@Q}"]++ ))



回答2:


Turn off multiple evaluation* of associative array subscripts with following command and it'll work.

shopt -s assoc_expand_once

* An example showing the default behavior and assoc_expand_once's effect:

$ v1=42
$ v2='$v1'
$ declare -A foo
$ foo[$v2]=
$ declare -p foo
declare -A foo=(["\$v1"]="" )
$ (( foo[$v2]++ ))
$ declare -p foo
declare -A foo=([42]="1" ["\$v1"]="" )
$
$ shopt -s assoc_expand_once
$ (( foo[$v2]++ ))
$ declare -p foo
declare -A foo=([42]="1" ["\$v1"]="1" )


来源:https://stackoverflow.com/questions/61701799/bad-array-subscript-error-when-trying-to-increment-an-associative-array-element

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!