2

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?

Lunartist
  • 394
  • 1
  • 3
  • 9

2 Answers2

1

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.

vdavid
  • 2,434
  • 1
  • 14
  • 15
1

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
markp-fuso
  • 28,790
  • 4
  • 16
  • 36