如何使用包含数组名称的第二个变量来引用现有的 bash 数组?

How can I reference an existing bash array using a 2nd variable containing the name of the array?

我在发布前搜索答案时最接近最有用的匹配项:

Iterate over array in shell whose name is stored in a variable

How to use an argument/parameter name as a variable in a bash script

How to iterate over an array using indirect reference?

我的尝试部分成功:

#!/bin/bash

declare -a large_furry_mammals
declare -a array_reference  
# I tried both declaring array_reference as an array and 
# not declaring it as an array.  no change in behavior.

large_furry_mammals=(horse zebra gorilla)


size=large
category=mammals

tmp="${size}_furry_${category}"
eval array_reference='$'$tmp

echo tmp=$tmp
echo array_reference[0]=${array_reference[0]}
echo array_reference[1]=${array_reference[1]}

输出

tmp=large_furry_mammals
array_reference[0]=horse
array_reference[1]=

预期

当我回显 array_reference[1] 时,我本以为会得到输出斑马线。

...但我遗漏了一些细微之处...

为什么我不能访问索引数组中索引 0 以外的元素? 这表明 array_reference 实际上并未被视为数组。

我不想复制数组。我想引用(将是什么)基于指向该数组的变量的静态数组,即 ${size}_furry_${category} -> large_furry_mammals.

我已经使用我发布的链接成功地实现了这里的一般想法,但前提是它不是数组。当它是一个数组时,它对我来说是下降的。

2018 年 12 月 5 日附录

bash 4.3 在这种情况下不可用。 @benjamin 的回答在 4.3 下确实有效。

我将需要遍历结果数组变量的内容。我给出的涉及哺乳动物的这个有点愚蠢的例子只是为了描述这个概念。实际上有一个真实世界的案例。我有一组静态引用数组,输入字符串将被解析为 select 哪个数组是相关的,然后我将遍历 selected 的数组。我可以做一个 case 语句,但有 100 多个引用数组,这将是直接但过于冗长的方法。

这个伪代码可能是我要追求的更好的例子。

m1_array=(x a r d)
m2_array=(q 3 fg d)
m3_array=(c e p)

Based on some logic...select which array prefix you need.
x=m1

for each element in ${x}_array
do
   some-task
done

我正在使用@eduardo 的解决方案进行一些测试,看看我是否可以调整他引用变量的方式以进入我的残局。

** 附录 #2 2018 年 12 月 14 日 **

解决方案

我找到了!使用@eduardo 的示例,我得出以下结论:

#!/bin/bash

declare -a large_furry_mammals
#declare -a array_reference

large_furry_mammals=(horse zebra gorilla)


size=large
category=mammals

tmp="${size}_furry_${category}[@]"

for element in "${!tmp}"
do
    echo $element
done

这是执行的样子。我们成功地迭代了动态构建的数组字符串的元素。

./example3b.sh

horse
zebra
gorilla

谢谢大家

declare -a large_furry_mammals
declare -a array_reference
large_furry_mammals=(horse zebra gorilla)

size=large
category=mammals

echo ${large_furry_mammals[@]}
tmp="${size}_furry_${category}"
array_reference=${tmp}"[1]"
eval ${array_reference}='bear'
echo tmp=$tmp
echo ${large_furry_mammals[@]}

如果您有 Bash 4.3 或更新版本,您可以使用 namerefs:

large_furry_mammals=(horse zebra gorilla)
size=large
category=mammals
declare -n array_reference=${size}_furry_$category
printf '%s\n' "${array_reference[@]}"

有输出

horse
zebra
gorilla

这是参考,因此更改会反映在 large_furry_mammalsarray_reference 中:

$ array_reference[0]='donkey'
$ large_furry_mammals[3]='llama'
$ printf '%s\n' "${array_reference[@]}"
donkey
zebra
gorilla
llama
$ printf '%s\n' "${large_furry_mammals[@]}"
donkey
zebra
gorilla
llama