calling other variables in a variable name (Bash)
langs
is not an array but a string in your code.
To make it an array and use it:
langs=( EN GE )
dir_EN=/xx
dir_GE=/zz
dir_ml=()
for i in "${langs[@]}"; do
declare -n p="dir_$i"
dir_ml+=( "$p" )
done
printf 'dir_ml = "%s"\n' "${dir_ml[@]}"
In the above loop, $i
will take the values EN
and GE
in turn. This also introduces a name reference variable p
. When the value of p
is accessed, the string that was assigned to the variable when it was declared will be interpreted as a variable name and that variable's value is returned.
The output of the above will be
dir_ml = "/xx"
dir_ml = "/zz"
To use name references in bash
, you will need bash
version 4.3 or later.
Another (interesting but inferior) possibility:
dir_EN=/xx
dir_GE=/zz
# (can't set dir_ml=() here as its name would be picked up by the loop)
unset dir_ml
for i in "${!dir_@}"; do
dir_ml+=( "${!i}" )
done
printf 'dir_ml = "%s"\n' "${dir_ml[@]}"
Here, $i
will take the values of the variable names dir_EN
and dir_GE
in turn. We then use variable indirection with ${!i}
to get the value of that variable. This variation does not need the langs
array, but it instead assumes that no other variable is named dir_
-something (which may be considered a bit fragile as a user may easily inject variables with names like these into the script's environment).
The output is the same for this code as for the code above.
This can be accomplished as follows:
#!/bin/bash
langs=(EN GE)
dir_EN=/xx
dir_GE=/zz
for i in ${!langs[@]}; do
temp="dir_${langs[i]}"
dir_ML[i]=${!temp}
done
First I have changed langs="EN GE"
to langs=(EN GE)
because this needs to be an array.
I have also changed $(seq 0 1)
to ${!langs[@]}
which will expand to the index (or name in the case of an associative array) of each item in the array. So in this example 0 1
.
Then I set a temp variable to dir_${langs[i]}
(dir_EN
and dir_GE
).
Then using the !
parameter expansion I expand the variable with that name to set the element of dir_ML