3

I am trying to write simple bash script where I need to create dynamically variables. Here is the code

#!/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

current output is

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

I need to be

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

Were I am wrong

3 Answers 3

2

Don't bother with dynamic variable names. Use an associative array to fake a multidimensional array

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
Sign up to request clarification or add additional context in comments.

Comments

2

eval is not the right tool here. You can either use 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

or you can use nameref (requires bash 4.3 or later):

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

or choose a better design, see glennjackman's answer.

1 Comment

@AntonAntonov please take a look at What should I do when someone answers my question?.
1

Your code is wrong for two reasons:

  1. Your currentvar array is not associative -- it is a regular array.

  2. As currentvar is a regular array, the items you put into are arranged using non-negative indices: 0, 1, and so on. Therefore, any expansion of ${currentvar[string]} is actually ${currentvar[0]}, i.e., the first item in the array. Hence, the same repeated value displayed.

1 Comment

Thank you! I'll be careful to avoid current mistakes

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.