Bash variable recursion

Not sure how to ask this question. I want concatenate strings and variable recursively into new variable. For example:

infile01=/dir/subfolder/file01.txt
infile02=/dir/subfolder/file02.txt
infile03=/dir/subfolder/file03.txt
for i in {01..03}
do
u=${"infile"$i}
echo $u
done

I got error message:

-bash: ${"infile"$i}: bad substitution

How do I get output?

/dir/subfolder/file01.txt
/dir/subfolder/file02.txt
/dir/subfolder/file03.txt

Thanks a lot!

Whatever you are trying to do is a bad programming practice.

I would highly recommend using arrays instead which is pretty much straightforward:

infile[1]="/dir/subfolder/file01.txt"
infile[2]="/dir/subfolder/file02.txt"
infile[3]="/dir/subfolder/file03.txt"

for i in {1..3}
do
        echo "${infile[$i]}"
done
1 Like

Or, I tried:

for i in {01..03}
do
u=$"infile"$i
echo $u
done

and got

infile01
infile02
infile03

but I was expecting

/dir/subfolder/file01.txt
/dir/subfolder/file02.txt
/dir/subfolder/file03.txt

---------- Post updated at 05:58 PM ---------- Previous update was at 05:55 PM ----------

Thanks Yoda!
I should have thought of that way.

You can use eval to acheive it, but using it is a security risk and hence a bad programming practice.

infile01=/dir/subfolder/file01.txt
infile02=/dir/subfolder/file02.txt
infile03=/dir/subfolder/file03.txt
for i in {01..03}
do
        u=$( printf "infile%02d" "$i" )
        eval echo \$"$u"
done

You need to use eval....here is a simple example

[root@localhost cgi-bin]# x1="foo"
[root@localhost cgi-bin]# n=1
[root@localhost cgi-bin]# eval echo \${x$n}
foo
1 Like

A little perspective is in order.

Would you pass untrusted data to find . -exec $untrusted_data \; ? Or rm $untrusted_data ?

Simply using eval is not a security risk nor is it bad practice.

Trusting untrustworthy data is the real problem and it is bad practice regardless of the tool involved.

Regards,
Alister

Hi Yoda!
Another question not about the concatenation but related to the array index when it is "08". The problem is with 8 & 9 that caused problem as

 "bash: 08: value too great for base (error token is "08"). "

I am aware this is related to octal for 01~07 but not 08~09.. etc. I want this leading 0 for 1~9 for the filenames to be nicely aligned. What is the trick to include a leading zero to the number as array index, if any? Thanks a lot!

Use Associative Arrays:

#!/bin/bash

typeset -A infile

infile["01"]="/dir/subfolder/file01.txt"
infile["02"]="/dir/subfolder/file02.txt"
infile["03"]="/dir/subfolder/file03.txt"
infile["04"]="/dir/subfolder/file04.txt"
infile["05"]="/dir/subfolder/file05.txt"
infile["06"]="/dir/subfolder/file06.txt"
infile["07"]="/dir/subfolder/file07.txt"
infile["08"]="/dir/subfolder/file08.txt"
infile["09"]="/dir/subfolder/file09.txt"

for i in {01..09}
do
        echo ${infile["$i"]}
done