7

I am trying to print a simple value for $AR1_p1 but the variable $i is not evaluating.

for i in 1 2 3 4
do
    AR1_p1=22
    AR1_p2=23
    AR1_p3=24
    AR1_p3=25
    echo $AR1_p$i
done 

It's like concatenating dynamically. Any suggestions on how to fix this?.

7
  • 1
    Perhaps the echo line should be: echo $AR1_p1$i
    – parkamark
    Jan 12, 2016 at 13:50
  • 1
    @parkamark, I want this to be dynamic like p1,p2 etc. Jan 12, 2016 at 13:52
  • 2
    You should use arrays instead. What you want is not possible (or at least very bad style).
    – Sven
    Jan 12, 2016 at 13:53
  • @Sven, I understand i can use arrays but since i have only 4 values to evaluate. So this is a problem with bash ?. Jan 12, 2016 at 13:55
  • @serverliving.com no, this is not a problem with Bash. Bash is behaving exactly the way it should, and this is indeed an issue for which it makes sense to use an array. Why is it an issue to use an array of 4 elements?
    – Jules
    Jan 12, 2016 at 16:57

5 Answers 5

24

You can use bash indirect references for that:

AR1_p1=22
AR1_p2=23
AR1_p3=24
AR1_p4=25
for i in 1 2 3 4
do
  VARNAME="AR1_p${i}"
  echo "${!VARNAME}"
done
0
7

Per suggested comment(s), array should be used:

#!/bin/bash

AR1_p=(22 23 24 25)

for i in {1..4}
do
  echo "${AR1_p[$i-1]}"
done
2
  • This doesn't make any sense. The for loop is an array assignment already...
    – mikeserv
    Jan 21, 2016 at 1:44
  • You are correct, it doesn't make any sense. As much as this has had up votes, it didn't fully address the true requirement of the original question. That was addressed in the other answer above relating to "bash indirect references" which is a better solution for what the OP was trying to achieve. My post does, however, demonstrates some of the intricacies that can be employed in BASH to achieve the same thing, noting that the above could simply be reduced to "for i in {22..25}; do echo $i; done", but that answer doesn't really have any relevance to the original question.
    – parkamark
    Jan 21, 2016 at 9:30
6

This loop works. Else use Arrays.

$ for i in 1 2 3 4; do AR1_p1=22; AR1_p2=23; AR1_p3=24; AR1_p4=25; echo $((AR1_p$i)); done 
22
23
24
25
1
  • 4
    Note this will only work for integer-valued parameters.
    – chepner
    Jan 21, 2016 at 1:01
3

Use eval:

#!/bin/bash

AR1_p1=22
AR1_p2=23
AR1_p3=24
AR1_p4=24
for i in 1 2 3 4
do
    eval echo \$AR1_p$i
done

echo expands only $i. When this expression reaches eval, it is like : $AR1_p1. Eval tries to evaluate and gives the result.

2
  • 7
    eval is usually a bad idea. In this example of course you aren't handling external input, but if you ever do you need to be very sure you sanitize any data you pass to eval. (Which is hard. Very hard. Better to just skip it.)
    – Wildcard
    Jan 12, 2016 at 16:22
  • 2
    @Wildcard - it isn't all that hard, really. And learning how to do it the right way shouldn't be skipped.
    – mikeserv
    Jan 21, 2016 at 1:33
0

POSIXly:

for i in 1 2 3 4
do  AR1_p1=22
    AR1_p2=23
    AR1_p3=24
    AR1_p4=25
    echo "$((AR1_p$i))"
done

A little less messy, maybe:

for i in 1 2 3 4
do  echo "$((AR1_p$i=i+21))"
done

Still POSIXly, but far more sensible:

i=0 n=21 l=4
while  [ "$l" -ge "$((i+=1))" ]
do     echo "$((AR1_p$i=i+n))"
done

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .