Reputation: 31
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
Upvotes: 3
Views: 268
Reputation: 7499
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.
Upvotes: 2
Reputation: 246774
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
Upvotes: 2
Reputation: 3115
Your code is wrong for two reasons:
Your currentvar
array is not associative -- it is a regular array.
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.
Upvotes: 1