Reputation: 464
Because bash doesn't support "arrays in arrays", I'm trying to dynamize variable name when calling arrays.
bash version : 4.2
I used this expansion method: https://stackoverflow.com/a/18124325/9336478
#!/bin/bash
# data are pre-defined and type is determined later
declare -a data_male
declare -a data_female
data_male=(value1 value2)
data_female=(value3 value4)
type="male"
for value in ${${!data_$type}[@]};do
echo $value
done
and it did not work
line 20: ${${!data_$type}[@]} : bad substitution
How do I sort this out?
Upvotes: 3
Views: 1797
Reputation: 34419
If OP can get a newer version of bash
installed then a nameref (name reference, available in bash 4.3+) could be used:
declare -a data_male
declare -a data_female
data_male=(value1 value2)
data_female=(value3 value4)
type="male"
declare -n arr="data_${type}" # dynamically declare arr[] as a name ref to data_male[]
for ndx in "${!arr[@]}"
do
echo "${arr[${ndx}]}"
done
This generates:
value1
value2
Upvotes: 3
Reputation: 2544
Unfortunately, in Bash 4.2 you need to eval
the array.
printf -v evaluator 'for value in ${%s[@]};do\n echo $value\ndone' "data_$type"
eval "$evaluator"
printf
will inject the name of the array designated by data_$type
into the %s
part, and then the result of the string is assigned to the variable evaluator
.
So, the first part builds a string designed to be evaluated, and then you evaluate it.
Instead of newline characters \n
you can also use actual newlines:
printf -v evaluator 'for value in ${%s[@]};do
echo $value
done' "data_$type"
eval "$evaluator"
You should make sure that the contents of your arrays are safe because this can be used to inject malicious code.
Upvotes: 2