0
#!/bin/bash
mat_1=(ServerAB ServerFR ServerPE ServerAM ServerHU)
st="mat_1";
indirect_var='${'${st}'[@]}'

#(Please, see the "--Desired Ouput Section--" in comments)

#----- What is Hapenning now at output ----
echo Values of "mat_1 ": ${mat_1[@]}
echo Indirect value of "mat_1": ${!indirect_var}

# echo Indirect value of "mat_1": ${!indirect_var}  ##output> ${mat_1[@]}
# But it is not recognized as a real ${mat_1[@]}.

# -- What actually have ----
for (( i=0; i < ${#mat_1[@]}; i++ )) #I would like just only make 
                                  #that loop accepts that 
                                  #string 'mat_1' and operate
                                  #normally as if I were typed 
                                  # ${#mat_1[@]} , like
                                  # ${#'string'[@]}, working all 
                                  # together as a real array declare
                                  # ${#mat_1[@]}, and I may re-utilize
                                  # this loop and make a function where
                                  #I pass--> function-name $1, where $1 is
                                  # an string, and this string already
                                  # exist above , it will interpret as
                                  # an existing array


do
echo ${mat_1[i]};
done

#And I would like those strings 
#that are part of the name of existing 
#variables , will be treated as an input
# and this loop works. I will show What I have done,
# what I have reached, and what I expect to have.
# Thank you!


#------What I expect works-----

#for (( i=0; i < ${#$st[@]}; i++ ))  #I would like $st works like 'mat_1'
                                  #and this loop can be run without 
                                  #problems
#do
#   echo ${$st[i]};
#done

#--- Actual Output ------------
#$ ./matrix.sh 
# Values of mat_1 : ServerAB ServerFR ServerPE ServerAM ServerHU
# ./matrix.sh: line 8: ${mat_1[@]}: invalid variable name
# ServerAB
# ServerFR
# ServerPE

#--- Desired Output ----------

#$ ./matrix.sh 
# Values of mat_1 : ServerAB ServerFR ServerPE ServerAM ServerHU
# Indirect Value of mat_1: ServerAB ServerFR ServerPE ServerAM ServerHU
# ServerAB
# ServerFR
# ServerPE
# ServerAM
# ServerHU

" Hi Friends, I would like some ideas to achieve the following".

  • I have many existing 'arrays vars' that I would like to be called within a for loop by 'concatenating strings' in order to form those ' existing array names'.But in the Script above I just only Working with 01 array 'var_mat1'. I jut only need work for 01 array...
    • Example of the existing 'array names':

      var_mat1=( ".." ".." ".." )
      var_mat2=( ".." ".." ".." )
           .
           .
           .
      var_matN=( ".." ".." ".." )
      
dcubaz
  • 23
  • 5
  • `$ ./matrix.sh Values of mat_1 : ServerAB ServerFR ServerPE ServerAM ServerHU Indirect value of mat_1: mat_1 ServerAB ServerFR ServerPE ServerAM ServerHU ` – dcubaz Apr 12 '21 at 16:48

2 Answers2

0

When using indirection, only use the variable's name (and possibly the index), but not the braces and the dollar sign.

indirect_var=$st[@]  # line 4.
choroba
  • 45,735
  • 7
  • 84
  • 110
  • Hi @choroba, thank you but it did not work, this is the actual output following your suggestion: ` $ ./matrix.sh Values of mat_1 : ServerAB ServerFR ServerPE ServerAM ServerHU Indirect value of mat_1: mat_1 ServerAB ServerFR ServerPE ServerAM ServerHU ` – dcubaz Apr 12 '21 at 16:45
  • I probably don't understand. That's what you have under "Desired output", right? – choroba Apr 12 '21 at 17:03
  • yeah this is why I expect, in Desired Output. – dcubaz Apr 12 '21 at 18:45
  • It's the output I'm getting. – choroba Apr 12 '21 at 18:49
  • thank you I hope you can help me with the output. – dcubaz Apr 12 '21 at 19:02
  • Please describe your problem. I don't understand. – choroba Apr 12 '21 at 19:06
  • To iterate over the array, use `for e in "${!indirect_var}" ; do echo "$e" ; done`. – choroba Apr 12 '21 at 19:09
  • I left another explanation, maybe now I can explained more accurate, lol – dcubaz Apr 12 '21 at 19:20
  • I would like just only make that loop accepts that string `'mat_1'` and operate normally as if I were typed `${#mat_1[@]}` , like `${#'string'[@]}`, working all together as a real array declaration `${#mat_1[@]}`, and I may re-utilize this loop and make a function where I pass--> `function-name $1`, where `$1` is an string, and this string already exist above , it will interpret as an existing array – dcubaz Apr 12 '21 at 19:21
0

It seems to me that you are having a hard time with using indirect variables.

To access an array variable called a:

a=(one two t33 f44)

you need an indirect variable that contains only what you would have written inside the ${...} construct. To get the value of ${a[2]} you need an indirect variable set to:

indirect=a[2]

And then, use it:

$ echo "<${!indirect}>"
<t33>

I believe that you should check what is in indirect_var='${'${st}'[@]}'.

Perhaps: indirect_var="${st}[@]" Your description is not clear enough for me to be sure.

But understand that changing the variable st alone won't access other variables/values. You must change the value of indirect_var before it works.

Try this script:

#!/bin/bash
mat_1=(ServerAB ServerFR ServerPE ServerAM ServerHU)
mat_2=(SeAB SeFR SePE SeAM SeHU)

st="mat_1";
#indirect_var='${'${st}'[@]}'
indirect_var="${st}[@]"
#(Please, see the "--Desired Ouput Section--" in comments)

#----- What is Hapenning now at output ----
echo "Values of mat_1        : ${mat_1[@]}"
echo "Indirect value of mat_1: ${!indirect_var}"

st=mat_2
echo "This WONT work"
echo "Values of mat_2        : ${mat_2[@]}"
echo "Indirect value of mat_2: ${!indirect_var}"

st=mat_2
indirect_var="${st}[@]"
echo "This DOES work"
echo "Values of mat_2        : ${mat_2[@]}"
echo "Indirect value of mat_2: ${!indirect_var}"


Perhaps you should forget about st and update indirect_var as needed.

Also, there is no way to get the count from the indirect variable, there is not a syntax like echo "${!#indirect_var}" but you can do perfectly fine with:

indirect_var="#mat_1[@]"
echo "${!indirect_var}"

Perhaps define a count_indirect_var="#$indirect_var" to get the count.

Good luck!.

  • Thank you so MUCH!, really I need to improve my english, but finally you did not get me wrong and Understood what I need. Thanks! – dcubaz Apr 12 '21 at 20:45
  • @dcubaz Please read the edited notes, I believe those will be helpful. Good luck! –  Apr 12 '21 at 21:16
  • I read and test it but it worked partially, within a for loop it does not work. :( – dcubaz Apr 13 '21 at 02:22
  • What is **it**? Care to be (a lot) more specific?. In which sort of "for loop" **it** doesn't work?. I believe that a new question is a sensible path to solve this **new** problem. @dcubaz –  Apr 13 '21 at 02:32