0

I am using MacBook pro terminal to execute a shell script. It loops through a text file and create filenames based on each line in the file.

#!/bin/bash

year=2010
list=list_test.txt

mydir=thisdir

i=1  # counter

while read line
do
    echo $i $line
    file1=`echo $mydir/file_$year_$line_test.tif`
    file2=`echo $mydir/file_$year_$line_test.tif`
    echo $file1 $file2 

    i=$(($i+1))

done < $list

However, the output is peculiar:

1 17019
thisdir/file_.tif thisdir/file_.tif
2 17029
thisdir/file_.tif thisdir/file_.tif
3 17039
thisdir/file_.tif thisdir/file_.tif

Within the loop, bash does not recognize some variables, like "year" which is a global, and "line" which is read from the text file. The text file is as below:

17019
17029
17039

Another script with exactly the same manner works very well. This is mysterious to me now.

Any help or comments are extremely appreciated! Thanks very much!

Kang
  • 25
  • 1
  • 5
  • You want `$mydir/file_${year}_${line}_test.tif` (with the curly brackets), otherwise Bash thinks you mean the variables `year_` and `line_test`. – gniourf_gniourf Sep 19 '17 at 16:51
  • Thank you! I understand now! – Kang Sep 19 '17 at 16:57
  • The process of building a [mcve] might have helped to narrow this down -- if you'd tried to reproduce with only the code `line=foo; year=2010; echo $mydir/file_$year_$line_test.tif`, it would have been obvious that the `read` loop is not required to produce this problem. – Charles Duffy Sep 19 '17 at 16:59

1 Answers1

2

_ is a valid character for an identifier, but you want to use it as a literal character in the file name. You need to use the full form of parameter expansion, ${x} instead of $x.

(Also, the command substitution isn't necessary.)

file1=$mydir/file_${year}_${line}_test.tif
file2=$mydir/file_${year}_${line}_test.tif
chepner
  • 497,756
  • 71
  • 530
  • 681
  • Thanks so much! It works now! Also thanks for the suggestion. Really appreciate it. – Kang Sep 19 '17 at 16:55