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
因为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