bash array of arrays
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
The minimum changes to make your script work correctly, it becomes:
#!/bin/bash
declare -a bar=("alpha" "bravo" "charlie")
declare -a foo=("delta" "echo" "foxtrot" "golf")
declare -a groups=("bar" "foo")
for group in "${groups[@]}"; 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
The two main changes are:
Don't use
"${!lst[@]}"
, not even"${!group[@]}"
to access array elements. This syntax is only to access array indexes.Do use
${!lst}"
.The variable lst should be set to contain the string that you would have written inside a normal
${ }
, that is:lst=foo[@]
on first level and tolst="$group[@]"
if you need that the name of the array is also indirect via the value of variablegroup
.lst="$group[@]"
An equivalent syntax with namerefs
has no !
(nor it needs) to expand values.
As a consequence it needs the [@]
removed above.
echo "using namerefs"
for group in "${groups[@]}"; 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