Re: zsh pattern-matching makes no sense...
Hi, what you need to understand is that globbing matches file
names.
* is the pattern that matches any sequence of characters. But
when it comes to globbing, there are two steps involves:
1- come up with a list of file names
2- apply the pattern to that list and only retain those that
are matched.
With "*", the file list is built as the list of the names of the
files in the current directory.
"/" is special in globbing patterns, that is well described in
the manual, and it's the same for every shell.
"*" doesn't match "foo/bar", the shell doesn't even have a look
at the content of "foo" to look for files matching "*". The
manual will say that "/" must be matched explicitely, but it
s if you also understand that the "/"s in the pattern will
also tell the shell, whose directory to read the content to make
a list of file paths to apply the pattern against.
In:
*foo*/*bar*, the shell will first find the directories (and only
directories) that match "*foo*" and then list their content and
apply the other pattern.
You can't do
(foo|bar/baz)/*.txt, that's described in the manual.
The "/", with its special status of telling the shell where to
look for files can't be put anywhere.
To allow for recursive globbing, zsh (and only zsh) has a well
defined exception, it's:
(<pattern>/)#foo
or
(<pattern>/)##<glob>
this also is described in the manual.
Above that tells zsh to recursively look for directories
matching the pattern and apply the <glob> on their content.
foo(*/)# is not of that special kind, it's not supported by zsh.
You could do:
**/*~^foo(|/*)
as what's after ~ is considered as a pattern that is applied to
the final list, it's not globbing, but it won't be efficient in
that every subdirectory of the current will be searched, not
only "foo".
If you read the manual again, you'll see that it's explained,
I'm not inventing it.
--
Stéphane
|