Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash scripting - Iterating through "variable" variable names for a list of associative arrays

I've got a variable list of associative arrays that I want to iterate through and retrieve their key/value pairs.

I iterate through a single associative array by listing all its keys and getting the values, ie.

for key in "${!queue1[@]}" do
    echo "key : $key"
    echo "value : ${queue1[$key]}"
done

The tricky part is that the names of the associative arrays are variable variables, e.g. given count = 5, the associative arrays would be named queue1, queue2, queue3, queue4, queue5.

I'm trying to replace the sequence above based on a count, but so far every combination of parentheses and eval has not yielded much more then bad substitution errors. e.g below:

for count in {1,2,3,4,5} do
    for key in "${!queue${count}[@]}" do
        echo "key : $key"
        echo "value : ${queue${count}[$key]}"
    done
done

Help would be very much appreciated!

like image 522
Indecided Avatar asked Nov 09 '12 09:11

Indecided


1 Answers

The difficulty here stems from the fact that the syntax for indirect expansion (${!nameref}) clashes with the syntax for extracting keys from an associative arrays (${!array[@]}). We can have only one or the other, not both.

Wary as I am about using eval, I cannot see a way around using it to extract the keys of an indirectly referenced associative array:

keyref="queue${count}[@]"
for key in $(eval echo '${!'$keyref'}'); do ... ; done

You can however avoid eval and use indirect expansion when extracting a value from an array given the key. Do note that the [key] suffix must be part of the expansion:

valref="queue${count}[$key]"
echo ${!valref}

To put this in context:

for count in {1..5} ; do
    keyref="queue${count}[@]"
    for key in $(eval echo '${!'$keyref'}'); do
        valref="queue${count}[$key]"
        echo "key = $key"
        echo "value = ${!valref}"
    done
done
like image 188
Shawn Chin Avatar answered Sep 29 '22 04:09

Shawn Chin