Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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?

share|improve this question
add comment

2 Answers

up vote 3 down vote accepted

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?

Because [] brackets indicate a list of matched characters (which can be digits), not numbers interpreted mathematically. Such pattern is matched against a single character. The list can contain ranges, but of digits or letters. [2-57] match expands to "All digits in the range from 2 to 5 and a 7".

To match numbers from 2 to 57, it would be easier to use a sequence expression instead of a globbing pattern (or together with such):

for x in /foo/bar/*{2..57}; do print $x; done

Edit: But this, unfortunately, will not give you lexicographical order of all listed files - they'd be grouped by common number endings due to shell expansion.

share|improve this answer
    
Thanks @rozcietrzewiacz! I should have thought about that. My files had numbers in them, so for a moment I thought [] was printing things in order.. –  user815423426 Nov 18 '11 at 23:34
    
Your explanation of [2-57] is correct, but I don't think {2..57} (that's what you meant, right?) is relevant to what intrpc wants to do, which is “pick the files 2 to 57 in lexicographical order”. –  Gilles Nov 19 '11 at 1:40
    
Thanks for the edit (time to go to sleep, I guess). And you're right - I'd forgotten about the lexicographical order part. –  rozcietrzewiacz Nov 19 '11 at 1:48
add comment

[2-57] is a character set consisting of 2, 3, 4, 5 and 7, 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 the numeric_glob_sort option is set); you can control it with the o or O glob qualifier (e.g. *(om[2,57]) to match the 57 most recent file except the one most recent file).

for x in /foo/bar/*([2,57]); do print $x; done

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.

echo hello{2..57}

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.

$ ls
file1 file2 file3 file57 file58
$ echo file<2-57>
file2 file3 file57

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>, with file5 matching the * part and 8 matching the <2-57> part. The pattern *[^0-9]<2-57> avoids this issue.

share|improve this answer
    
You are right. I was misremembering the glob qualifier. Thanks for the careful explanation. –  user815423426 Nov 25 '11 at 21:50
    
By the way, this statement got me a bit confused: if you want to enumerate files 2 to 57 whether they exist or not, you can use a range brace expression. If the files don't exist and there are no matches, how would the brace expansion know how to expand? (how would it expand differently from the glob qualifier?) –  user815423426 Nov 25 '11 at 21:52
2  
@intrpc foo{8..11}bar expands to foo8bar foo9bar foo10bar foo11bar. This bit of expansion is unrelated to file names. Similarly, foo{eight,nine,ten,eleven}bar expands to fooeightbar fooninebar footenbar fooelevenbar. This is brace expansion in ksh/bash/zsh. –  Gilles Nov 25 '11 at 21:55
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.