0

I have a Bash script where i have calculated many values and stored them in the variables which have a number for each row. For instance, i have a variable named as TC_5 which calculates the value of 5th row of the input csv file. I have calculated all the values and stored in variables which have the naming convention of TC_<Row_No> so that for 200 rows i have values stored in:

TC_1
TC_2
.
.
TC_200

Now, i want to write a loop which could print the values of all these variables together to an external file instead of manually printing them. For this, i am using the while loop as follows:

i=0
while [ "$i" != 201 ]
do
    echo "TC_$i" >> Out
    i=`expr $i + 1`
done

How can i modify the above code in such a way that the echo statement would print the variable TC_<RowNo> to the Out File?

3
  • Why not use awk/sed? Sep 22, 2015 at 8:03
  • 1
    Do you hear about arrays?
    – Costas
    Sep 22, 2015 at 8:25
  • Hello Guys, could you please provide your suggestions as answers? I don't want to do it strictly with while loop. Any other option which is faster and better would be appreciated. Of course i have heard about arrays :) Sep 22, 2015 at 9:29

3 Answers 3

2

Your current script stuck in an infinitive loop, because the condition [ "$i" != 201 ] was always true.

You must increase $i after each iteration and using eval to print the content of TC_<RowNo> variable (but it's not safe):

i=1
while [ "$i" -ne 201 ]
do
    eval printf '%s\\n' "\${TC_$i}"
    i=$((i+1))
done >> "Out"

Note that $i started at 1, the use of -ne for integer comparison and the redirection at the end of while loop.

1
  • Good point cuonglm. Actually i missed to put the increment statement in the above example. That is present in my main script. Thanks for your answer. I will try it and get back to you. Sep 22, 2015 at 9:06
1

The preferred way to do this sort of thing in bash is to use an array:

TC[1]=something
TC[2]=somethingelse
...
TC[200]=somethingstillelse

i=1
while ((i <= 200)); do
    echo "${TC[i]}" >> Out
    ((i++))
done

But if you really want to embed the indexes in plain variable names, you can use an indirect variable reference:

TC_1=something
TC_2=somethingelse
...
TC_200=somethingstillelse

i=1
while ((i <= 200)); do
    varname=TC_$i    # Need to store the variable name in a variable first
    echo "${!varname}" >> Out    # The ! (and braces) trigger indirect expansion
    ((i++))
done

Note that neither of these features are available in basic POSIX shells like dash. Make sure your script is running under bash, not a generic shell.

-1

I changed your while loop slightly and it worked for me:

i=1
while [ "$i" != 201 ]
do
    echo $TC_$i >> Out
    i=`expr $i + 1`
done

Note the $ in front of TC_$i and the removal of the double quotes. (I included the modification cuonglm suggested for the starting value.)

(Using GNU bash in iTerm on a Mac running High Sierra.)

4
  • 1
    Really?  That doesn't work for me.   (Are you sure you're using bash?) Feb 13, 2019 at 2:47
  • ~/CertificateTest/save 499> /bin/sh --version GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin17) Copyright (C) 2007 Free Software Foundation, Inc. Feb 13, 2019 at 7:34
  • No, $TC_$i would expand to the concatenation of the values of the variables TC_ and i.
    – Kusalananda
    Feb 13, 2019 at 9:19
  • And yet, it really did work for me on GNU bash... Feb 13, 2019 at 17:14

You must log in to answer this question.

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