Bash: 如何将变量作为关联数组名称使用

3
我正在编写一个Bash脚本,简化从我们的主站点到多个机构的文件复制。在这个脚本中,我尝试将一个变量作为关联数组的名称,但是出现了错误。以下是代码:
#!/bin/bash

declare -A GROUP1
declare -A GROUP2
declare -A GROUP3
declare -A ARRAY

GROUP1["SITE1"]="x.x.x.x"
GROUP1["SITE2"]="y.y.y.y"
GROUP1["SITE3"]="z.z.z.z"

GROUP2["SITE1"]="1.1.1.1"
GROUP2["SITE2"]="2.2.2.2"
GROUP2["SITE3"]="3.3.3.3"

GROUP2["SITE1"]="a.a.a.a"
GROUP2["SITE2"]="b.b.b.b"
GROUP2["SITE3"]="c.c.c.c"

read -p "Choose a group of sites : " group

case $group in
    1 ) DEST="GROUP1" ;;
    2 ) DEST="GROUP2" ;;
    3 ) DEST="GROUP3" ;;
esac

eval "ARRAY=(\${$DEST[@]})"

for elem in "${!ARRAY[@]}"
do
   echo $elem
   echo ${ARRAY[$elem]}
done

以下是错误信息:

./test: line28: TAB : 3.3.3.3 : must use subscript when assigning associative array
./test: line28: TAB : 2.2.2.2 : must use subscript when assigning associative array
./test: line28: TAB : 1.1.1.1 : must use subscript when assigning associative array

我能做的事情是否可能?
预先感谢。
1个回答

2

如果你有bash v4.3版本,那么这是可能的,但并不容易。使用4.3版本,你可以使用"nameref"来实现:

declare -A GROUP1
declare -A GROUP2
declare -A GROUP3

GROUP1["SITE1"]="x.x.x.x"
#...

# Yuk. Use command-line options, not stdin
read -p "Choose a group of sites : " group

for g in GROUP1 GROUP2 GROUP3; do if [[ $group == $g ]]; then

  # Here's the nameref: After this executes, ARRAY is an alias for
  # the indicated variable.
  declare -n ARRAY=$group
  break

fi

### This is documented but might not work depending on bash version
### Instead you could test for existence of a known key:
###    if [[ ! -v ${ARRAY[SITE1]} ]]; then
if [[ ! -R ARRAY ]]; then
 echo "No such group" >> /dev/stderr; exit 1
fi

好的,你可能还没有bash 4.3版本,但将来上面的内容对某些人会很有用。因此,在没有它的情况下,您可以采用类似于您提出的策略,即复制指定的关联数组。如果数组不太大,那么这并不太糟糕。为此,请使用上面的方法,但将nameref行 (declare -n ARRAY=$group) 替换为以下内容:

defn=$(declare -p $group)
eval "${defn/$group/ARRAY}"
unset defn

在这种情况下,您需要使用替代的成功测试。
注意:对于bash变量名称使用全部大写并不是一个好主意。惯例是系统生成的环境变量和shell内置变量使用全部大写。用户变量应该使用小写字母,以避免与这些预定义变量发生冲突。

感谢你的回答,rici。我忘记了不要为用户变量使用大写字母。我明天会尝试你的建议。 - Jaymzwise

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接