You are probably familiar with globbing. Globbing is a way to select files on the command line based on a simple pattern. For instance, to remove all files within a directory, you can use:
That's basically it. The asterisk says: “match all characters, regardless of how often they appear”. Other globbing operators are
? meaning “match any single character” and
[xyz] meaning “match any character within the square brackets” (you can also specify ranges such as
That's about what all shells support. Newer versions of Bash can do a lot more, but I'll show you what the Z Shell can do.
Before we dive right into globbing and expansion, we have to clarify some basics. Unlike Bash, ZSH can expand almost everything. Therefore you won't find much about this topic if you search the manual for globbing. It's all called expansion or filename generation because that's what it is: ZSH globbing is not just a pattern, ZSH globbing is more like a different way of naming things and you can always hit TAB, to expand the expression. For instance, try this on the command line:
% ls dir/*<TAB>
Once you hit the TAB key, ZSH will expand the globbing operator and list all matched files instead. This works with any other globbing operator as well.
That's it for the basics, now let's start with the fun part. I promise, this is much more powerful than normal globbing or even normal regex matching rules.
Note: to be able to use all the extended expansion/globbing features, you need to set the option
EXTENDED_GLOB first. So execute:
before doing anything else or better place it in your
This is one of the most important things to know and it is probably also the feature, you'd be presented with first, when reading any Z Shell globbing guide. Recursive globbing is the feature, that makes the
find command superfluous in most circumstances because with this you can search the current directory including all subdirectories. To match any file
foo within the current directory also including subdirectories, run:
Notice the double asterisk. This will list all files named
foo in the current directory tree. If you also want to follow symlinks, use
*** instead of
Nearly every globbing pattern can be negated. To match any file not starting with the letters a or b the following pattern can be used:
The negation operator can be used in front of any pattern, not just inside square brackets. For example:
will find any files except
will find any files except
bar. You see: you can also use parentheses to group patterns and use the pipe character to separate alternatives just like in normal regular expressions.
This is a very useful feature. With approximate matching you find files even if their names contain spelling mistakes such as differing, missing or transposed characters.
matches all files with the name
foobar but also files with the names
foxbar. The number after the
a defines how far the correction goes. A number of 1 corrects up to one mistake. Higher numbers do more correction. But be careful: the more correction you allow, the more false positives you'll get.
With qualifiers it is possible to select files by certain attributes and this is where ZSH globbing becomes very powerful. The list of qualifiers is extremely long, so I'll pick the most important ones. Qualifiers are parenthesis expressions at the very end of the whole globbing expression. If the
BARE_GLOB_QUAL option is set, you can use bare parentheses or otherwise use
foo is the qualifier.
First of all there are file type qualifiers. We have
. for regular files,
/ for directories,
@ for symbolic links,
= for sockets and
p for named pipes. Now to list all symbolic links inside the directory
More qualifiers are
* for any executable files,
x for owner readable, writable or executable files. These are usually enough, but of course there are lots of other qualifiers, including extended access rights, time and file size selectors. All of these can of course be combined as you like. Definitely have a look at the man page.
That concludes this little introduction. If what you've read here does not sound exciting, then be aware that this is just a very little part of what's possible with ZSH-style globbing. If I'd write about everything you could do with it, it would grow to the size of a book. But I strongly advise you read the manual which I linked below.
To give you one example of how powerful the whole thing is, let me show you one expression to recursively match all normal files which have no uppercase characters or numbers in the name, which are executable for the owner who must have the UID 1002 but not for the rest of the world, have a file size above 30MB and have been modified within the last month:
ls -l **/([^A-Z[:digit:]])##(#q.x^X^u1002Lm+30mM-1)
And if you hit TAB instead of Enter, ZSH will of course expand the whole expression on the command line. Got it? Fine!
Read more about extended globbing and expansion:
- zsh.sf.net: Expansion
- zsh.sf.net: Glob Qualifiers
- zsh.sf.net: Introduction to Filename Generation
- Globbing wildcard characters with zsh
- OpenClassrom: ZSH Globbing