a1="one"
a2="two"
a3="three"
for ((i=1;i<=3;i=i+1)); do
echo $a$i
done
I have already tried following
echo ${a$i}
echo $((ai))
echo ${a}${i}
c=$(echo a$i)
But none gave the right answer.
a1="one"
a2="two"
a3="three"
for ((i=1;i<=3;i=i+1)); do
echo $a$i
done
I have already tried following
echo ${a$i}
echo $((ai))
echo ${a}${i}
c=$(echo a$i)
But none gave the right answer.
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
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.
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
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?