5

I have a script that iterates over an array of values, something like this (dumbed down for the purposes of this question) :

COUNTRIES=( ENGLAND SCOTLAND WALES )

for i in ${COUNTRIES[@]}
do                  
    echo "Country is $i "
done

My question is, is it possible to substitute the array dynamically? For example, I want to be able to pass in the array to iterate over at runtime. I've tried the following but I think my syntax might be wrong

COUNTRIES=( ENGLAND SCOTLAND WALES )
ANIMALS=( COW SHEEP DOG )

loopOverSomething()
{
    for i in ${$1[@]}
    do                  
        echo "value is $i "
    done
}

loopOverSomething $ANIMALS

I'm getting line 22: ${$2[@]}: bad substitution

Jimmy
  • 16,123
  • 39
  • 133
  • 213

3 Answers3

4

You can use bash's indirect expansion for this:

loopOverSomething()
{
    looparray="$1[@]"
    for i in "${!looparray}"
    do
        echo "value is $i"
    done
}
Gordon Davisson
  • 118,432
  • 16
  • 123
  • 151
0

You could use the array as argument in the following way:

COUNTRIES=( ENGLAND SCOTLAND "NEW WALES" )
ANIMALS=( COW SHEEP DOG )

loopOverSomething()
{
    for i in "$@"
    do                  
        echo "value is $i "
    done
}

loopOverSomething "${ANIMALS[@]}"
loopOverSomething "${COUNTRIES[@]}"
sgibb
  • 25,396
  • 3
  • 68
  • 74
  • 1
    -1 for not using quotes -- if `countries=( "New Wales" England )`, "New" and "Wales" would be treated as separate entries. – Charles Duffy May 17 '12 at 15:38
0

This is covered by BashFAQ #006:

We are not aware of any trick that can duplicate that functionality in POSIX or Bourne shells (short of using eval, which is extremely difficult to do securely). Bash can almost do it -- some indirect array tricks work, and others do not, and we do not know whether the syntax involved will remain stable in future releases. So, consider this a use at your own risk hack.

# Bash -- trick #1.  Seems to work in bash 2 and up.
realarray=(...) ref=realarray; index=2
tmp="$ref[$index]"
echo "${!tmp}"            # gives array element [2]

# Bash -- trick #2.  Seems to work in bash 3 and up.
# Does NOT work in bash 2.05b.
tmp="$ref[@]"
printf "<%s> " "${!tmp}"; echo    # Iterate whole array.
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441