Reputation: 507
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.
Upvotes: 1
Views: 796
Reputation: 2020
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]"
Upvotes: 0
Reputation: 12267
For the line
ls file{$a..$b}
you could use instead:
eval ls file{$a..$b}
Check [Bash Reference].
Upvotes: 1
Reputation: 140940
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
Upvotes: 2