Guneet
Guneet

Reputation: 55

Accessing indirect shell variables in Bash

I have 13 filenames and i want to pass them as argument in sh

File is like:

$FILEPATTERN = "XYZ_"

FILENAME1="$FILEPATTERN${somedate1}_{sometime}.csv"
FILENAME2="$FILEPATTERN${somedate2}_{sometime}.csv"
FILENAME3="$FILEPATTERN${somedate3}_{sometime}.csv"
...
FILENAME13="$FILEPATTERN${somedate13}_{sometime}.csv"

for g in 1 2 3 4 5 6 7 8 9 10 11 12 13
do
  filenewname=FILENAME${g}
  sh $SCRIPTS/$SCRIPTNAME $filenewname
  filenewname=""
done

when i echo the filenewname, it is printing FILENAME1, FILENAME2....

Expected output should be value inside variable FILENAME1 i.e $FILEPATTERN${somedate1}_{sometime}.csv

Upvotes: 2

Views: 457

Answers (3)

tk421
tk421

Reputation: 5957

Use eval. Eval expands it's arguments before executing them and is the standard way in shell scripts to do what you want.

$ FILEPATTERN=XYZ_
$ somedate1=20170515
$ FILENAME1="$FILEPATTERN${somedate1}_{sometime}.csv"
$ eval filenewname=$FILENAME1
$ echo $filenewname
XYZ_20170515_{sometime}.csv
$ 

Upvotes: 0

codeforester
codeforester

Reputation: 43039

You need ${!var} construct to access the indirect shell variable. So, rewrite the loop as:

for g in 1 2 3 4 5 6 7 8 9 10 11 12 13
do
  filenewname="FILENAME${g}"
  sh "$SCRIPTS/$SCRIPTNAME" "${!filenewname}"
done

Or, more simply:

for g in {1..13}; do
  filenewname="FILENAME$g"
  sh "$SCRIPTS/$SCRIPTNAME" "${!filenewname}"
done

I have added double quotes around the variables to prevent word splitting and globbing.

As an aside, your first line has a problem - $FILEPATTERN = "XYZ_" is not a valid assignment. It should be FILEPATTERN="XYZ_" (note: no spaces around =). Check your script at shellcheck.


Using all caps for normal shell variables isn't a good practice. See this post for some useful info regarding naming convention:

Upvotes: 4

jesus_is_a_lie
jesus_is_a_lie

Reputation: 1

My first time trying to answer a question, but why not use an array for your file names?

#Make an array called 'arr' with 13 strings of our file names 
FILEPATTERN="XYZ_"
arr=(`for i in {1..13}; do echo "$FILEPATTERN${somedate}$i_${sometime}";done`)

I don't know where you're getting ${somedate} and ${sometime} but if the only difference between each of the 13 files is the number at the end, you can pre-generate the filenames like shown above.

#Now loop through that array and perform operations
for name in "${arr[@]}"; do
    echo "Handling $name..."
    sh $SCRIPTS/$SCRIPTNAME $name
done

If this helps, you could also just do it on the fly:

FILEPATTERN="XYZ_"
for i in {1..13}; do
    echo "Handling $name..."
    sh $SCRIPTS/$SCRIPTNAME $FILEPATTERN${somedate}"$i"_${sometime}
done

Upvotes: -1

Related Questions