Append an index number to a variable name in bash?
I am trying to loop through numbered variables but am having a hard time appending the loop index number to the base variable name. Code follows, using a 2-iteration example:
#ENTER TOTAL NUMBER OF RUNS HERE:
nruns=2
# START DATE/TIME #END DATE/TIME
#***************** ***************
#RUN 1 #RUN 2 #RUN 1 #RUN2
yr1=2008; yr2=2008; eyr1=2008; eyr2=2008;
mo1=11; mo2=12; emo1=12; emo2=12;
day1=30; day2=1; eday1=2; eday2=3;
hr1=18; hr2=18; ehr1=00; ehr2=00;
min1=00; min2=00; emin1=00; emin2=00;
sec1=00; sec2=00; esec1=00; esec2=00;Then I try to loop through this such that I can append the run number to the base variable name which is the only thing that stays the same (eg appending 1,2,3..etc to yr and then calling the $yr1 $yr2 $yr3 ... etc variables as defined above)
for count in `seq 1 $nruns`
do #start vars #********** ystart=$((yr$count)) mostart=$((mo$count)) daystart=$((day$count)) hrst=$((hr$count)) # but this removes my preceding 0 which I need. i.e, # here I get 0 instead of 00 minst=$((min$count)) secst=$((sec$count)) # Similarly, for end time variables #end vars #********** yend=$((eyr$count)) moend=$((emo$count)) dayend=$((eday$count)) hrend=$((ehr$count)) minend=$((emin$count)) secend=$((esec$count))Now I try to make strings that I am using to substitute into a program file, but because of the above issues I get the following:
sd1=$ystart-$mostart-$daystart\_$hrst:$minst:$secst #which gives me 2008-11-30_18:0:0 instead of 2008-11-30_18:00:00 ed1=$yend-$moend-$dayend\_$hrend:$minend:$secend #which gives me 2008-12-2_0:0:0 instead of 2008-12-02_00:00:00Any assistance would be greatly appreciated. Thank you!
1 Answer
The first problem is that you're asking about a different problem than the one you're having...
To start with a very literal answer: If you want to access a variable whose name is in another variable, you can use "indirect expansion" – the ${!...} operator. For example:
var=yr$i; ystart=${!var}
var=mo$i; mostart=${!var}
...However, what you're doing by appending an index number to variable names, is just inefficiently emulating an array variable, even though bash already has arrays as a built-in data type:
yr=() # declare `yr` to be an empty array
mo=()
yr[1]=2008
mo[1]=11
yr[2]=2009
mo[2]=01
for (( i=1; i <= nruns; i++ )); do echo "Date: ${yr[i]}-${mo[i]}-${day[i]}"
done(You can also iterate over all 'keys' using for i in ${!yr[@]}.)
Finally, just to answer the last example: If you want to zero-pad numbers, you can use the printf command with format strings similar to those in C:
yr=2009
mo=4
day=7
hr=11
min=5
printf "%d-%02d-%02d %02d:%02d\n" $yr $mo $day $hr $min
# -> 2009-04-07 11:05Here %d means a decimal number (the distinction between %d and %s is important in C but they're almost interchangeable in bash). %2d will make it at least 2 characters long and right-aligned (use negative width to left-align); %02d makes it zero-padded rather than space-padded.
printf "[%d] [%-4d] [%03d]\n" 1 2 3 # -> [1] [2 ] [003] 0