Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I get this error using {1..9} in zsh?

I run the following code

zgrep -c compinit /usr/share/man/man{1..9}/zsh*

I get

zsh: no matches found: /usr/share/man/man2/zsh*

This is strange, since the following works

echo Masi{1..9}/masi

This suggests me that the problem may be a bug in Zsh.

Is the above a bug in Zsh for {1..9}?

like image 607
Léo Léopold Hertz 준영 Avatar asked Apr 30 '09 04:04

Léo Léopold Hertz 준영


People also ask

Which is better bash or zsh?

Zsh is built on top of bash thus it has additional features. Zsh is the default shell for macOS and Kali Linux. Zsh provides the user with more flexibility by providing various features such as plug-in support, better customization, theme support, spelling correction, etc.

What is zsh on Mac?

The Z shell (also known as zsh ) is a Unix shell that is built on top of bash (the default shell for macOS) with additional features. It's recommended to use zsh over bash . It's also highly recommended to install a framework with zsh as it makes dealing with configuration, plugins and themes a lot nicer.


2 Answers

It's not a bug, and it is working inside words fine. The trouble you're having here is that {1..9} is not a wildcard expression like * is; as your echo example shows, it's an iterative expansion. So your zgrep example is exactly the same as if you had typed each alternate version into the command line, and then since there are no man pages starting with zsh in man2, it errors out. (It's erroring out on a failure to find a match, not anything intrinsically related to your brace sequence expansion.)

If you did this, on the other hand:

zgrep -c compinit /usr/share/man/man[1-9]/zsh*

you'd get the results you expect, because [1-9] is a normal wildcard expression.

like image 142
chaos Avatar answered Sep 18 '22 20:09

chaos


In zsh, if you want to use ranges in filenames, zle offers <1-n> on any real names it can expand on. That is to say:

$ touch a0b a1b a5b a7b
$ print a<0-100>b

And then hit <Tab> right after the final b would leave you with print a0b a1b a5b a7b expanded on the line.

For all other intents and purposes - perhaps full range requirements, non-file and scripting use - I'd express this using the rather succinct idiomatic zsh loop as:

for n ({1..50}); do print $n; done

Will allow you process the whole sequence range of numbers 1 to 50 :) after which you can do all sorts of useful things with, such as a file collection that doesn't exist yet:

arr=($(for n ({1..50}); do print /my/path/file$n.txt; done)) && print $arr[33]
like image 37
Rob Jens Avatar answered Sep 21 '22 20:09

Rob Jens