1

Im trying double loop using array values like array names for loop

array1="name1 name2"
name1="one two"
name2="red blue"

for name in $array1
do 
  for value in $name
  do
    echo "$name - $value"
  done
done

I need to use 'name' to '$name' for use in 2nd loop, but this don't work for me.
How could I use value of array1 like the name of array inside 2nd loop?

3 Answers 3

5

That's not how you define arrays in bash.

a="foo bar"

defines a string/scalar variable. And using it as $a (unquoted) performs the split+glob operator which only makes sense for strings representing a $IFS separated list of file patterns.

In bash, arrays are defined as:

a=(foo bar)

So here, you'd want:

array1=(name1 name2)
name1=(one two)
name2=(red blue)


for name in "${array1[@]}"
do
  typeset -n nameref="$name"
  for value in "${nameref[@]}"
  do
    printf '%s\n' "$name - $value"
  done
done

typeset -n is a relatively recent addition to bash and declares a nameref, that is a variable that contains the name of another variable and when expanded actually refers to the named variable.

4
  • in the printf statement, $name prints first element of arrays.. how to print name1 and name2 instead?
    – Sundeep
    Jun 10, 2016 at 7:44
  • 1
    @spasic. Ah good point, I missed that. See edit. Jun 10, 2016 at 9:02
  • Nameref is a quite recent 4.3 option. Using Indirection instead: nameref="${name}[@]"; for value in "${!nameref}" works with bash from the very old version 2.0 of 1997.
    – user79743
    Jun 10, 2016 at 22:10
  • Perfect !!! Now I undestand arrays better. Thanks a lot Stephane... Jun 13, 2016 at 12:35
2

A simple change from for value in $name to for value in ${!name} will make your script work correctly:

array1="name1 name2"; name1="one two"; name2="red blue"

for       name  in $array1     ; do 
    for   value in ${!name}    ; do
          printf '%s - %s\n' "$name" "$value"
    done
done

However, it should be pointed that the variable called array1 is an string, not an array, no at all.
If you wish to work with arrays:

#!/bin/bash

array1=(name1 name2)
name1=(one two)
name2=(red blue)

for       name  in "${array1[@]}"     ; do
          ref="${name}[@]"
    for   value in "${!ref}"          ; do
          printf '%s - %s\n' "$name" "$value"
    done
done

Indirection works from bash 2.0 (1997) and up. Instead of nameref which is a recent 4.3 addition.

1

As Stéphane Chazelas points out, a list of words is not the same an array. However, you can use indirect expansion like this:

array1="name1 name2"
name1="one two"
name2="red blue"

for name in ${array1}
do
    for value in ${!name}
    do
        echo "$name - $value"
    done
done

In this case, ${!name} introduces a level of indirection.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .