bash 中的动态数组名称

问题描述

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

bash 版本:4.2

我使用了这种扩展方法https://stackoverflow.com/a/18124325/9336478

#!/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

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...