1

I can create some files in my dir using template:

touch file{1..3}

For get list of files I use command:

ls file{1..3}

Output:

file1 file2 file3

But when I have tried to use same command with variables in bash script:

#/bin/bash
a=1
b=3
ls file{$a..$b}

I got error:

ls: cannot access 'file{1..3}': No such file or directory

How I understand problem is that bash interprets file{1..3} as name of file, but not as template.
I have tried to fix it but didn't help. Any help would be appreciated.

ERemarque
  • 497
  • 3
  • 16

3 Answers3

2

Because Brace Expansion happens before Variable Expansion (see order of expansions).

So bash sees:

file{$a..$b}

and first tries to do brace expansion. As $a and $b (interpreted as dollar with a character, this is before variable expansion) are not a valid brace expansion token, because they need to be a single character or a number, so nothing happens in brace expansion. After it (and some other expansions) variable expansion happens and $a and $b get expanded to 1 and 3, so the resulting argument is "file{1..3}".

For you simple use case, with no spaces and/or special characters in fielnames, I would just:

ls $(seq -f file%.0f "$a" "$b")

or

seq -f file%.0f "$a" "$b" | xargs ls

or

seq "$a" "$b" | xargs -I{} ls file{}

or

seq "$a" "$b" | sed 's/^/file/' | xargs ls

or

seq "$a" "$b" | xargs printf "file%s\n" | xargs ls
KamilCuk
  • 120,984
  • 8
  • 59
  • 111
1

For the line

ls file{$a..$b}

you could use instead:

eval ls file{$a..$b}

Check [Bash Reference].

mao
  • 11,321
  • 2
  • 13
  • 29
0

For a more general type solution, ditching the ls could be potentially to use find. For example in combination with regex, although this might be tricky (see How to use regex with find command?):

#!/bin/bash
a=1
b=3
find . -regex "./file[$a-$b]"
B.Kocis
  • 1,954
  • 20
  • 19
  • It is not so good way. Let's say that we have 100 files. In this case I should set `b=100`. Script will show only file `./file1` – ERemarque Sep 12 '19 at 11:19
  • for that case: `find . -regex "./file[0-9]+"`. I mean, you can modify the regex as it fits your real problem. :) https://www.ntu.edu.sg/home/ehchua/programming/howto/Regexe.html – B.Kocis Sep 12 '19 at 11:30
  • Yes, this could be different cases. Therefore I need correctly find files with required ranges of numbers in names for checking. It can 20, 30 or 100 files, why I use variables in script. – ERemarque Sep 12 '19 at 12:42