Bash Scripting – How to Create an Array of Arrays

arraybashindexingshell-script

Trying to write some nested loop, and I'm not getting how to write it. Perhaps I'm looking in a wrong direction but what I'm trying to write is:

declare -a bar=("alpha" "bravo" "charlie")
declare -a foo=("delta" "echo" "foxtrot" "golf")

declare -a subgroups=("bar" "foo")

So then I would like to iterate the subgroups (in the future more bars and foos will come), and inside them iterate them as they can have a different number of elements.

The desired output would be something like:

group name: bar with group members: alpha bravo charlie
        working on alpha of the bar group
        working on bravo of the bar group
        working on charlie of the bar group
group name: foo with group members: delta echo foxtrot golf
        working on delta of the foo group
        working on echo of the foo group
        working on foxtrot of the foo group
        working on golf of the foo group

The closes code I've wrote seems fail in the bar and foo arrays and its expansion with the elements on each set.

for group in "${subgroups[@]}"; do
   lst=${!group}
   echo "group name: ${group} with group members: ${!lst[@]}"
   for element in "${!lst[@]}"; do
       echo -en "\tworking on $element of the $group group\n"
   done
done

And the output is:

group name: bar with group members: 0
        working on 0 of the bar group
group name: foo with group members: 0
        working on 0 of the foo group

Best Answer

This is a pretty common problem in bash, to reference array within arrays for which you need to create name-references with declare -n. The name following the -n will act as a nameref to the value assigned (after =). Now we treat this variable with nameref attribute to expand as if it were an array and do a full proper quoted array expansion as before.

for group in "${subgroups[@]}"; do
    declare -n lst="$group"
    echo "group name: ${group} with group members: ${lst[@]}"
    for element in "${lst[@]}"; do
        echo -en "\tworking on $element of the $group group\n"
    done
done

Note that bash supports nameref's from v4.3 onwards only. For older versions and other workarounds see Assigning indirect/reference variables

Related Question