2

I am trying to do an indirect reference to values in an array in bash.

anotherArray=("foo" "faa")

foo=("bar" "baz")
faa=("test1" "test2")


for indirect in ${anotherArray[@]}
do

echo ${!indirect[0]}
echo ${!indirect[1]}

done

This does not work. I tried a lot of differenct things to get the different values of $foo by echoing $indirect but I can only get the first value, all values, '0' or nothing at all.

1

3 Answers 3

4

You have to write the index in the variable used for indirection :

anotherArray=("foo" "faa")
foo=("bar" "baz")
faa=("test1" "test2")

for indirect in ${anotherArray[@]}; do
  all_elems_indirection="${indirect}[@]"
  second_elem_indirection="${indirect}[1]"
  echo ${!all_elems_indirection}
  echo ${!second_elem_indirection}
done

If you want to iterate over every element of every arrays referenced in anotherArray, do the following :

anotherArray=("foo" "faa")
foo=("bar" "baz")
faa=("test1" "test2")

for arrayName in ${anotherArray[@]}; do
  all_elems_indirection="${arrayName}[@]"
  for element in ${!all_elems_indirection}; do
    echo $element;
  done
done

Alternatively you could directly store the whole indirections in your first array : anotherArray=("foo[@]" "faa[@]")

Sign up to request clarification or add additional context in comments.

1 Comment

Okay, I thought there might be a more elegant way to do this instead of assigning every single value of the array to a separate variable to use it in the loop. Thanks!
3

Modern versions of bash adopt a ksh feature, "namevars", that's a perfect fit for this issue:

#!/usr/bin/env bash
case $BASH_VERSION in ''|[123].*|4.[012]) echo "ERROR: Bash 4.3+ needed" >&2; exit 1;; esac

anotherArray=("foo" "faa")

foo=("bar" "baz")
faa=("test1" "test2")

for indirectName in "${anotherArray[@]}"; do
  declare -n indirect="$indirectName"
  echo "${indirect[0]}"
  echo "${indirect[1]}"
done

Comments

1

You need do it in two steps

$ for i in ${anotherArray[@]}; do 
     t1=$i[0]; t2=$i[1]; 
     echo ${!t1} ${!t2};  
  done

bar baz
test1 test2

2 Comments

It's not exactly two steps, he could set anotherArray=("foo[@]" "faa[1]") and the indirections would access the specific elements rather than just the first.
Yes, there can be infinitely many more variations but that's not what the OP is asking for.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.