我的脚本有一堆以字符串“versions_”开头的变化变量,例如:
versions_a=("1" "2")
versions_b=("3" "4")
我想循环这些变量并访问底层数组:
#!/usr/bin/env bash
versions_a=("1" "2")
versions_b=("3" "4")
for i in ${!versions_*}; do
#Ideally if statement here if underlying array is empty, continue to next iteration
echo "${i} contains ${i[*]}"
versions=(${!i})
echo "versions has ${versions[@]}"
for x in "${versions[@]}"; do
echo ${x} #should print 1, then 2, then 3, then 4
done
done
预期输出:
versions_a has 1 2
versions has 1 2
1
2
versions_b has 3 4
versions has 3 4
3
4
电流输出:
versions_a contains versions_a
versions has 1
1
versions_b contains versions_b
versions has 3
3
答案1
最简单的方法是在这里使用 nameref (假设 bash 4.3 或更高版本):
#! /bin/bash -
versions_a=( 1 2 )
versions_b=( 3 4 )
versions_c=( -n '*' )
for varname in "${!versions_@}"; do
typeset -n versions="$varname"
IFS=,
printf '%s\n' "$varname contains ${versions[*]}"
for x in "${versions[@]}"; do
printf '%s\n' "$x"
done
done
这使:
versions_a contains 1,2
1
2
versions_b contains 3,4
3
4
versions_c contains -n,*
-n
*
另请记住,参数扩展应加引号,并且echo
不能用于输出任意数据。并且"$*"
或的扩展"${array[*]}"
取决于 的当前值$IFS
(此处通过将其设置为 进行演示,
)。
答案2
看这个答案:
棘手的是,您必须将数组元素(或
[@]
所有元素)包含在您间接通过的变量中。
...或者[*]
如果这就是您想要的。像这样的东西:
#!/usr/bin/env bash
versions_a=("1" "2")
versions_b=("3" "4")
versions_c=()
for i in ${!versions_*}; do
group=${i#*"_"} #removes the 'versions_'
versions="${i}[@]"
last_version=${!versions: -1}
if [[ -z ${last_version} ]]; then
echo "Empty, skipping."
continue
fi
echo "${i} as ${group} has ${!versions}"
for x in "${!versions}"; do
echo "${group} & ${x}"
done
done
输出
versions_a as a has 1 2
a & 1
a & 2
versions_b as b has 3 4
b & 3
b & 4
Empty, skipping.