Tim Holdsworth
Tim Holdsworth

Reputation: 499

Iterate over array of array names expanding each to its members

I'd like create an array of subarrays made of strings, and get all the subarray values at once for each subarray in the main array.

For example, I'm hoping to get "str1" "str2" to print out the first time, but instead it actually prints out "sub1"

#!/bin/bash
declare -a arr=(sub1 sub2)
declare -a sub1=("str1" "str2")
declare -a sub2=("str3" "str4")

for item in "${arr[@]}"; do
  echo $item
done 

I want this behavior so I can later call a script and pass "str1" "str2" to an argument that takes two values. Then I'd like to run the script again with "str3" "str4"

Upvotes: 4

Views: 155

Answers (2)

oguz ismail
oguz ismail

Reputation: 50750

Set the nameref attribute for the loop's control variable (i.e. item), so that it can be used in the loop body as a reference to the variable specified by its value.

declare -n item
for item in "${arr[@]}"; do
  echo "${item[@]}"
done

Alternatively, as Ivan suggested, you can append [@] to each name and use indirect expansion on the control variable.

for item in "${arr[@]/%/[@]}"; do
  echo "${!item}"
done

For further information, see:

Upvotes: 5

Ivan
Ivan

Reputation: 7277

A few more variants beside of what @oguzismail suggested, first:

declare -a sub1=("str1" "str2")
declare -a sub2=("str3" "str4")
declare -a arr=("${sub1[*]}" "${sub2[*]}")

for item in "${arr[@]}"; do
  echo $item
done

Second:

declare -a arr=(sub1 sub2)
declare -a sub1=("str1" "str2")
declare -a sub2=("str3" "str4")

for item in "${arr[@]}"; do
  name="$item[@]"
  echo "${!name}"
done

Upvotes: 2

Related Questions