I've got several files in a folder, with the following names:
FILE_201.txt
FILE_206.txt
FILE_215.txt
FILE_223.txt
FILE_229.txt
FILE_232.txt
I want to select files between two values (e.g. between "210" and "230"). From the command line, running
ls -1 FILE_{210..230}.txt
lists the desired files; no problem. However, if I run the following Bash script,
#!/bin/bash
ls -1 FILE_{$1..$2}.txt
passing 210
and 230
as arguments to it, it doesn't work.
What am I doing wrong?
The problem isn't about running the command at the command line or from a script. You can check that for yourself, by running the following at the command line:
$ set 210 230 # assigns variables $1 and $2 the values "210" and "230", resp.
$ ls -1 FILE_{$1..$2}.txt
ls: FILE_{210..230}.txt: No such file or directory
As you can see, you get the same error as the one raised by your script file. The problem is that brace expansion happens before variable expansion.
In this case, by the time, $1
and $2
get expanded to 210
and 230
, it's too late for the range to be interpreted as such; the { .. }
part simply sticks around, without any special meaning attached to it.
Anyway, using ls
here is a bad idea, because you're going to get an error for each filename in the range that doesn't match an existing file. You'd be better off using a combination of a for loop and seq
, as in this answer:
#!/bin/bash
# test.sh
for n in $(seq $1 $2); do
f="FILE_$n.txt"
if [ -e $f ]; then
printf $s\\n "$f"
fi
done
Example:
$ touch FILE_209.txt
$ touch FILE_213.txt
$ touch FILE_224.txt
$ touch FILE_232.txt
$ bash test.sh 210 230
FILE_213.txt
FILE_224.txt