1

I would like to ask some help regarding variable variables in bash. I've read a few articles about it, but in my case I don't know how to do it. Let see my problem:

The array contains other arrays' names and I want to print the values of these arrays. In inner for I need variable variables.

#!/bin/bash
declare -a array=(dir1 dir2 dir3)
declare -a dir1=(1 2 3)
declare -a dir2=(a b c)
declare -a dir3=(9 8 7)

for elem1 in "${array[@]}"
do
  for elem2 in "${variableVariable[@]}"
  do
    echo "$elem1 : $elem2"
  done
done

The output should be something like this

dir1 : 1
dir1 : 2
dir1 : 3
dir2 : a
dir2 : b
dir2 : c
dir3 : 9
dir3 : 8
dir3 : 7
Zombo
  • 1
  • 62
  • 391
  • 407
AndrasCsanyi
  • 3,943
  • 8
  • 45
  • 77
  • 2
    Don't use variable variables in this case. Use [associative arrays](http://stackoverflow.com/questions/1494178/how-to-define-hash-tables-in-bash). – Alex May 02 '13 at 05:52
  • 1
    possible duplicate of [Lookup shell variables by name, indirectly](http://stackoverflow.com/questions/1694196/lookup-shell-variables-by-name-indirectly) – tripleee May 02 '13 at 06:01
  • Thanks Guys! The links are useful! – AndrasCsanyi May 02 '13 at 07:29
  • @tripleee It's similar to that question, but there's some extra work you have to do to deal with `[@]` when indirecting. It took me a while to figure it out. – Barmar May 02 '13 at 07:34
  • Mine problem is the how to deal with `[@]` part of the script. Can you help me? – AndrasCsanyi May 03 '13 at 18:02

2 Answers2

7

This can be done using bash's indirect variable feature.

for elem1 in "${array[@]}"
do
  elems=$elem1'[@]'
  for elem2 in "${!elems}"
  do
    echo "$elem1 : $elem2"
  done
done

Note that this is a bash extension, it's not portable to other shells.

Barmar
  • 741,623
  • 53
  • 500
  • 612
0

Finally, I found the solution. I had to use eval because I was not able to deal with the other syntax, I mean the composition of the ${!variable} and the ${variable[@]}.

#!/bin/bash
declare -a array=(dir1 dir2 dir3)
declare -a dir1=(1 2 3)
declare -a dir2=(a b c)
declare -a dir3=(9 8 7)

for elem1 in "${array[@]}"
do
  for elem2 in `eval echo \$\{$elem1\[@\]\}"`
  do
    echo "$elem1 : $elem2"
  done
done
AndrasCsanyi
  • 3,943
  • 8
  • 45
  • 77