5

猫测试.sh

#!/bin/bash
key="index";
arr[$key]="val"
echo ${arr[${key}]}

/bin/bash-x test.sh

+ key=index
+ arr[$key]=val
+ echo val
val

然后我修改test.sh:

#!/bin/bash
key="index.index";
arr[$key]="val"
echo ${arr[${key}]}

/bin/bash -x test.sh

+ key=index.index
+ arr[$key]=val
test.sh: line 3: index.index: syntax error: invalid arithmetic operator (error token is ".index")
test.sh: line 4: index.index: syntax error: invalid arithmetic operator (error token is ".index")

为什么会出现此错误,任何建议将不胜感激!

4

3 回答 3

7

这个:

key="index";
arr[$key]="val"
echo ${arr[${key}]}

似乎只工作。由于arr是普通数组,而不是关联数组,因此只能由非负整数值索引。

考虑这个有效的代码:

index=42
key="index"
arr[$key]="val"
echo ${arr[42]}
echo ${arr[index]}
echo ${arr[$index]}
echo ${arr['index']}
echo ${arr["index"]}
echo ${arr[\index]}

所有的echo报表都打印出来val。由于索引被视为算术表达式,因此它可以引用$index带有或不带有$前缀的变量(在本例中为 )——即使它是带引号的字符串。

在您的代码中,您从未为 分配值$index${arr[${key}]}扩展为${arr[index]},相当于${arr[$index]},它被视为(默认情况下)相当于${arr[0]}

(如果您有set -o nounset,那么对未设置变量的引用将被视为错误,您的代码将产生错误消息。)

你的第二段代码:

key="index.index";
arr[$key]="val"
echo ${arr[${key}]}

是无效的,因为index.index它不是一个有效的变量名——即使您可能意味着它只是一个用作数组索引的字符串。

如果你想arr允许任意字符串作为索引,它需要是一个关联数组。您可以简单地通过分配给它(或使用declare -a)来创建非关联数组,但只能使用 来创建关联数组declare -A

在版本 4 中将关联数组添加到 bash。如果您使用的是早期版本的 bash,declare -A则不支持。您需要升级到更新的 bash,编写一些笨拙的替代方案,或者使用支持关联数组的语言,如 Awk、Python 或 Perl。

添加declare -A arr(正如user000001 的回答所暗示的那样)应该可以解决问题(如果您有 bash 4),但是了解您的原始代码实际上在做什么(或者说不做什么)是有启发性的。

(顺便说一句,感谢您提出这个问题;在撰写此答案时,我学到了很多东西。)

于 2013-08-15T15:42:24.187 回答
6

用 将数组变量声明为关联数组declare -A arr

$ cat test.sh 
#!/bin/bash
set -x 
declare -A arr
key="index.index";
arr["$key"]="val"
echo "${arr["${key}"]}"

$ ./test.sh 
+ declare -A arr
+ key=index.index
+ arr["$key"]=val
+ echo val
val
于 2013-08-15T10:36:48.037 回答
1

此行为因 BASH 版本而异。旧的 BASH 版本只允许非负整数作为数组中的键。

请注意,dot/periodBASH 中不允许在变量名中使用。

有关 BASH 中允许的字符的更多详细信息,请参阅此问答:Linux 环境变量名称中的允许字符

编辑:

(非常感谢@chepner 提供此附录)

常规数组(非关联数组)仅由整数索引。任何用作方括号之间索引的表达式都被视为算术表达式。$key 扩展为 index,然后将其视为扩展为 0 的(未设置)变量。如果您为 index 分配了一个值,例如 3,则${array[$key]} -> ${array[index]} -> ${array[3]}. 这是一种隐式间接参数扩展

于 2013-08-15T10:44:21.903 回答