25
x=1
c1=string1
c2=string2
c3=string3

echo $c1
string1

I'd like to have the output be string1 by using something like: echo $(c($x))

So later in the script I can increment the value of x and have it output string1, then string2 and string3.

Can anyone point me in the right direction?

codeforester
  • 34,080
  • 14
  • 96
  • 122
user316100
  • 261
  • 1
  • 3
  • 5

3 Answers3

37

See the Bash FAQ: How can I use variable variables (indirect variables, pointers, references) or associative arrays?

To quote their example:

realvariable=contents
ref=realvariable
echo "${!ref}"   # prints the contents of the real variable

To show how this is useful for your example:

get_c() { local tmp; tmp="c$x"; printf %s "${!tmp}"; }
x=1
c1=string1
c2=string2
c3=string3
echo "$(get_c)"

If, of course, you want to do it the Right Way and just use an array:

c=( "string1" "string2" "string3" )
x=1
echo "${c[$x]}"

Note that these arrays are zero-indexed, so with x=1 it prints string2; if you want string1, you'll need x=0.

Charles Duffy
  • 257,635
  • 38
  • 339
  • 400
  • excellent. After your edit it becomes crystal clear and my preferred choice. Thanks very much for your time and knowledge. – user316100 Apr 15 '10 at 20:28
3

Try this:

eval echo \$c$x

Like others said, it makes more sense to use array in this case.

Hai Vu
  • 34,189
  • 11
  • 57
  • 87
  • 3
    Using eval without doing appropriate quoting (as with `printf %q`) is quite dangerous from a security perspective, particularly if your script is handling any data which could potentially be made by malicious or untrusted processes. (Even a filename could be used to inject malicious content, if that's what you were looping over). – Charles Duffy Nov 17 '11 at 14:27
2

if you have bash 4.0, you can use associative arrays.. Or you can just use arrays. Another tool you can use is awk

eg

awk 'BEGIN{
  c[1]="string1"
  c[2]="string2"
  c[3]="string3"
  for(x=1;x<=3;x++){
    print c[x]
  }
}'
ghostdog74
  • 307,646
  • 55
  • 250
  • 337