2
a1="one" a2="two" a3="three" for ((i=1;i<=3;i=i+1)); do echo $a$i done 

I have already tried following

  1. echo ${a$i}
  2. echo $((ai))
  3. echo ${a}${i}
  4. c=$(echo a$i)

But none gave the right answer.

0

4 Answers 4

5

That ((i=1;i<=3;i=i+1)) is ksh93 syntax (now also supported by bash and zsh (though you need blanks in between for and (( in zsh)).

In ksh93 and in recent versions of bash (4.3, 2014 or above), you can do:

a1="one" a2="two" a3="three" for ((i=1;i<=3;i=i+1));do typeset -n name="a$i" printf '%s\n' "$name" done 

In zsh, you can use variable indirection syntax: ${(e)code} (since May 1996), ${(P)name} (since 1999)

a1="one" a2="two" a3="three" for ((i=1;i<=3;i=i+1));do name=a$i printf '%s\n' "${(P)name}" # or code="\$a$i" printf '%s\n' "${(e)code}" # or combined: printf '%s\n' "${(e):-\$a$i}" "${(P)${:-a$i}}" done 

bash also added its own variable indirection feature, but using a different syntax (in 2.0 in December 1996), and one that means almost the opposite of that of ksh93:

a1="one" a2="two" a3="three" for ((i=1;i<=3;i=i+1));do name=a$i printf '%s\n' "${!name}" done 

With any POSIX shell, (including but not limited to ksh93, bash or zsh), you can always do:

a1="one" a2="two" a3="three" i=1; while [ "$i" -le 3 ]; do name=a$i eval "value=\${$name}" printf '%s\n' "$value" i=$((i + 1)) done 
3

In bash, if you have a variable containing the name of the variable you want, you can use indirection to access it:

a1="one" a2="two" a3="three" for((i=1;i<=3;i=i+1));do name="a$i" printf '%s\n' "${!name}" done 

if you use ${...} to expand a parameter, and the first character is ! then the rest is treated as the name of parameter that itself contains the name of the parameter you want to access.

0
2

If you are using Bash, the easiest way to accomplish the same thing is to use an array:

a[1]="one" a[2]="two" a[3]="three" for ((i=1; i<=3; i=i+1)); do echo "${a[$i]}" done 

You can also loop over the array:

for value in "${a[@]}"; do echo "$value" done 
0

If one must go down this route, in bash the following works. The idea is to use eval:

#!/bin/bash a1="one" a2="two" a3="three" for ((i=1;i<=3;i=i+1)); do var="a${i}" eval out=\$${var} echo $out done 

Output:

one
two
three

The eval approach allows for obtaining the value of a referenced variable. So once we have the variable name itself (above, in var as "a${i}" which will be a1, a2, etc), then it is possible to obtain the value of the variable through the eval built-in.

There is some discussion here: What is the "eval" command in bash?

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.