0

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?

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.

  • in the printf statement, $name prints first element of arrays.. how to print name1 and name2 instead? – Sundeep Jun 10 '16 at 7:44
  • 1
    @spasic. Ah good point, I missed that. See edit. – Stéphane Chazelas Jun 10 '16 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 '16 at 22:10
  • Perfect !!! Now I undestand arrays better. Thanks a lot Stephane... – Eloy Sanchez Jun 13 '16 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.