I would like to specify a range of files (in lexicographical order) with two integers (e.g. 2 to 57) in zsh by globbing.
For example: "pick the files 2 to 57 in lexicographical order under the path that matches some globbing pattern".
I thought using square brackets would do it
for x in /foo/bar/*[2-57]; do print $x; done
but zsh apparently thinks I am asking for the files 2
to 5
(or something like that) instead of files 2
to 57
. Any thoughts why? How can I accomplish this?
Best Answer
[2-57]
is a character set consisting of2
,3
,4
,5
and7
, in zsh and every other wildcard and regexp syntax out there. Your glob pattern*[2-57]
matches every filename whose last character is one of those five digits.I think you are misremembering the syntax of the
[m,n]
glob qualifier. Glob qualifiers always go in parentheses at the end of the pattern, and the range separator is a comma. The pattern*([2,57])
expands to the 2nd, 3rd, …, 57th matches. The default expansion order is lexicographic (with some special magic to sort numbers in numeric order if thenumeric_glob_sort
option is set); you can control it with theo
orO
glob qualifier (e.g.*(om[2,57])
to match the 57 most recent file except the one most recent file).Not what you asked for, but related and possibly useful to future readers: if you want to enumerate files 2 to 57 whether they exist or not, you can use a range brace expression. This feature also exists in bash and ksh.
And if you want to match files whose name contains a number between 2 and 57, you can use the pattern
<2-57>
. This is specific to zsh.Note that a pattern like
*<2-57>
is likely not to do what you expect, because the*
could match digits too. For example,file58
matches*<2-57>
, withfile5
matching the*
part and8
matching the<2-57>
part. The pattern*[^0-9]<2-57>
avoids this issue.