我想编写一个脚本来引用另一个数组中的多个数组,该数组保存这些数组的变量名称。
到目前为止,这是我的代码:
#!/bin/bash
array1=('array1string1' 'array1string2')
array2=('array2string1' 'array2string2')
array_names=('array1' 'array2')
for a in ${array_names[@]}
do
for b in ${a[@]}
do
echo $b
done
done
我希望输出扫描两个数组(从外部 for 循环)并在调用 echo 的内部 for 循环中打印相应的字符串。我当前的输出只是向我展示:
array1
array2
对于任何有关此问题的指示,我将不胜感激。谢谢你!
答案1
Bash 4.3 及更高版本支持“名称引用”或 namerefs(类似的概念存在于 中ksh93
,但是范围的不同令人烦恼):
#!/bin/bash
array1=('array1string1' 'array1string2')
array2=('array2string1' 'array2string2')
array_names=('array1' 'array2')
for a in "${array_names[@]}"; do
declare -n arr="$a"
for b in "${arr[@]}"; do
echo "$b"
done
done
该变量是一个 nameref,其作用类似于命名变量(本例中arr
具有 name 的变量)的别名。$a
如果没有 namerefs,在早期的 Bash 版本中,一种解决方案是创建一个新数组,其中包含其他数组中的所有元素:
all=( "${array1[@]}" "${array2[@]}" )
...有点像array_names
问题中的数组,但包含所有数组的内容,然后迭代"${all[@]}"
.
也可以使用eval
,但生成的代码看起来非常糟糕。
看格伦·杰克曼的回答具有变量间接的变体(在 Bash 版本 2 中以当前形式引入)。
答案2
@Kusalananda 对最新版本的 bash 有最好的答案。对于早期版本,您可以使用间接变量:
for a in ${array_names[@]}; do
tmp="${a}[@]"
for b in "${!tmp}"; do echo "$b"; done # or: printf "%s\n" "${!tmp}"
done
参见第 4 段https://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameter-Expansion
答案3
作为上述内容的变体:
#!/bin/bash
array1=('array1 string1' 'array1 string2')
array2=('array2 string1' 'array2 string2')
array_names=('array1' 'array2')
for (( i=0; i<${#array_names[@]}; i++ )); do
declare -n arr="${array_names[i]}"
for (( j=0; j<${#arr[@]}; j++ )); do
echo "${arr[j]}"
done
done
通过索引访问元素