bash 中的动态数组名称

Dynamic array name in bash

因为bash不支持“数组中的数组”, 我正在尝试在调用数组时动态化变量名。

bash 版本:4.2

我用的是这种扩展方式:

#!/bin/bash
# data are pre-defined and type is determined later

declare -a data_male
declare -a data_female

data_male=(value1 value2)
data_female=(value3 value4)

type="male" 

for value in ${${!data_$type}[@]};do
  echo $value
done

它没有用

line 20: ${${!data_$type}[@]} : bad substitution

我该如何解决这个问题?

不幸的是,在 Bash 4.2 中你需要 eval 数组。

printf -v evaluator 'for value in ${%s[@]};do\n  echo $value\ndone' "data_$type"
eval "$evaluator"

printf会将data_$type指定的数组名注入到%s部分,然后将字符串的结果赋给变量evaluator .

因此,第一部分构建了一个旨在进行评估的字符串,然后您对其进行评估。

除了换行符 \n 你还可以使用 actual 换行符:

printf -v evaluator 'for value in ${%s[@]};do
  echo $value
done' "data_$type"
eval "$evaluator"

您应该确保数组的内容是安全的,因为这可以用来注入恶意代码。

如果 OP 可以安装更新版本的 bash,则可以使用 nameref(名称参考,在 bash 4.3+ 中可用):

declare -a data_male
declare -a data_female

data_male=(value1 value2)
data_female=(value3 value4)

type="male"

declare -n arr="data_${type}"       # dynamically declare arr[] as a name ref to data_male[]

for ndx in "${!arr[@]}"
do
    echo "${arr[${ndx}]}"
done

这会生成:

value1
value2