2

I'm trying to compare the first character of each line of a buttload of files with the format filename.number.ext where number is a 4-digit number (0001, 0015, 5403, etc). My script goes like this:

 n=$1
 awk '{print $1}' filename.0001.ext > temp1.dat
 for i in {0002..$n}
   do
     echo $i
     awk '{print $1}' filename.$i.ext > temp.dat
     diff temp1.dat temp.dat
   done

This works fine if, instead of an input, I use a fixed value for the number of files, like so:

 awk '{print $1}' filename.0001.ext > temp1.dat
 for i in {0002..0345}
   do
     echo $i
     awk '{print $1}' filename.$i.ext > temp.dat
     diff temp1.dat temp.dat
   done

However, with the first version if I input 0345 for example, the shell returns

 $ myscript.sh 0345
 {0002..0345}
 awk: cannot open filename.{0002..0345}.ext (No such file or directory)

I'm a little lost here. I insist on using {0002..0345} over seq because all the file numbers have a fixed length of 4.

Régence
  • 21
  • 1

1 Answers1

2

A variable cannot be used in brace expansion. You need to use C-style for loop:

for (( i = 0002; i <= $n; i++ )); do
    true  # do whatever
done

See Bash Reference Manual for details.

4ae1e1
  • 7,228
  • 8
  • 44
  • 77
  • Or of course you can use `seq`. – 4ae1e1 Apr 15 '15 at 10:00
  • Thank you, but then how do I make sure that my indices are in a 4-digit form? – Régence Apr 15 '15 at 10:47
  • 1
    @Régence Use `printf %04d $i` or `for i in $(seq -w 2 n)`. – 4ae1e1 Apr 15 '15 at 10:49
  • Agree that `seq -w` is a good way to go. Unfortunately, it does not allow you specifically to set the padding, so if this _were_ an issue you can combine the two with `xargs`, e.g. `seq 2 9 | xargs printf "%04d\n"` – Component 10 Apr 15 '15 at 11:45
  • Thank you all for your input. I solved my problem by using `for i in {0002..9999}` and putting a `break` after n iterations. Not very elegant but it works well for my purpose. – Régence Apr 16 '15 at 14:30