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

时间:2018-11-30 22:56:31

标签: arrays bash loops for-loop indirection

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

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。

我将需要遍历结果数组变量的内容。我给出的涉及哺乳动物的这个愚蠢的例子只是为了描述这个概念。实际上,这是一个现实世界的案例。我有一组静态引用数组,并且将解析一个输入字符串以选择哪个数组是相关的,然后循环遍历所选数组。我可以执行一个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

谢谢大家。

2 个答案:

答案 0 :(得分:1)

如果您具有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

答案 1 :(得分:0)

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[@]}