user3507094
user3507094

Reputation: 224

How do you reference a variable within another variable in bash?

I am trying to do something which I thought would be fairly simple but not having any joy.

If I run the following, it successfully pulls the region (reg) from an array called PORT330 and checks to see it contains the value of $i. For example, it could be checking to see if "Europe London" contains the word "London". Here is what works:

if [[ ${PORT330[reg]} == *"$i"* ]] ; then 
   echo 302 is in $i ; 
fi

However, I actually have a list of Port array's to check so it may be PORT330, PORT550 and so on. I want to be able to substitute the port number with a variable but then call it within a variable. Here is what I am trying to do:

This works:

for portid in ${portids[@]} ; do 
  for i in ${regions[@]} ; do 
    if [[ ${PORT330[reg]} == *"$i"* ]] ; then 
      echo $portid is in $i ; 
    fi  ;
  done ; 
done

However this doesn't work:

for portid in ${portids[@]} ; do 
  for i in ${regions[@]} ; do 
    if [[ ${PORT$portid[reg]} == *"$i"* ]] ; then 
      echo $portid is in $i ; 
    fi  ; 
  done ; 
done

It throws this error:

-su: ${PORT$portid[reg]}: bad substitution

Any pointers as to where I am going wrong?

Upvotes: 0

Views: 28

Answers (1)

Dima Chubarov
Dima Chubarov

Reputation: 17169

In BASH variable expansion there is an option to have indirection via the ${!name} and ${!name[index]} schemes

for portid in ${portids[@]} ; do 
   for i in ${regions[@]} ; do 
      arr=PORT$portid
      if [[ ${!arr[reg]} == *"$i"* ]] ; then 
          echo $portid is in $i ; 
      fi  ; 
    done ; 
done

Here is a complete example

PORT330[reg]=a ; 
PORT550[reg]=b ; 
for portid in 330 550 ; do 
   for i in a b ; 
       do arr=PORT$portid ; 
       if [[ ${!arr[reg]} == *"$i"* ]] ; then 
           echo $portid is in $i ; 
       fi  ; 
   done ; 
done

Produces

330 is in a
550 is in b

Another example

:~> portids=(330 350 )
:~> echo ${portids[@]}
330 350
:~> PORT350[reg]=London
:~> PORT330[reg]=Berlin
:~> for portid in ${portids[@]} ; do arr=PORT$portid ; echo ${!arr[reg]} ; done
Berlin
London

Upvotes: 1

Related Questions