bash动态创建变量

时间:2018-01-10 21:44:17

标签: bash

我正在尝试编写简单的bash脚本,我需要创建动态变量。这是代码

#!/bin//bash
declare -A var12
        var12["a"]=1
        var12["s"]=2
        var12["c"]=3
declare -A var22
        var22["a"]=10
        var22["b"]=20
        var22["c"]=30
declare -A var32
        var32["a"]=100
        var32["b"]=200
        var32["c"]=300
declare -a variables=(12 22 32)
for i in ${variables[@]}
do
        echo $i
        eval currentVar=( \${var$i[@]} )
        echo ${currentVar["a"]} ${currentVar["b"]} ${currentVar["c"]}
done

当前输出

12
1 1 1
22
10 10 10
32
100 100 100

我需要

12
1 2 3
22
10 20 30
32
100 200 300

我错了吗

3 个答案:

答案 0 :(得分:2)

eval不是正确的工具。您可以使用variable indirection

#!/usr/bin/env bash

declare -A var12=([a]=1 [b]=2 [c]=3)
declare -A var22=([a]=10 [b]=20 [c]=30)
declare -A var32=([a]=100 [b]=200 [c]=300)

declare -a variables=(12 22 32)

for i in "${variables[@]}"; do
    echo "$i"
    current_a="var$i[a]"
    current_b="var$i[b]"
    current_c="var$i[c]"
    echo "${!current_a} ${!current_b} ${!current_c}"
done
# var="arr[@]" -> ${!var} is also possible:
for i in "${variables[@]}"; do
    echo "$i"
    current="var$i[*]"
    echo "${!current}"
done

或者您可以使用nameref(需要bash 4.3或更高版本):

for i in "${variables[@]}"; do
    declare -n current="var$i"  
    echo "$i"
    echo "${current[a]} ${current[b]} ${current[c]}"
done

或选择更好的设计,请参阅glennjackman's answer

答案 1 :(得分:2)

不要打扰动态变量名。使用关联数组伪造多维数组

declare -A var=(
    [12,a]=1    [12,s]=2    [12,c]=3
    [22,a]=10   [22,s]=20   [22,c]=30
    [32,a]=100  [32,s]=200  [32,c]=300
)
variables=( 12 22 32 )

for i in "${variables[@]}"; do 
    for j in a s c; do 
        printf "%s\t%s\t%s\n" $i $j "${var[$i,$j]}"
    done
done
12      a       1
12      s       2
12      c       3
22      a       10
22      s       20
22      c       30
32      a       100
32      s       200
32      c       300

答案 2 :(得分:1)

您的代码错误有两个原因:

  1. 您的currentvar数组不是关联的 - 它是常规数组。

  2. 由于currentvar是常规数组,因此您输入的项目使用非负索引排列:0,1,依此类推。因此,${currentvar[string]}的任何扩展实际上都是${currentvar[0]},即数组中的第一项。因此,显示相同的重复值。