Bash:访问对数组的间接引用

Bash:访问对数组的间接引用

我的脚本有一堆以字符串“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.

相关内容