Zsh: select files with arbitrary code in (e) or + glob qualifiers

Zsh glob qualifiers can select files by many built-in attributes: type, size, modification time, and more. But when no built-in qualifier fits, you can bring in the e or + qualifiers to run arbitrary code, making globs a fully programmable file filter. With great power comes great responsibility!
The e syntax looks like this: extend your glob, like *, with (e:'CODE':), replacing CODE with your Zsh code to run. : is an arbitrary delimiter, and the quoting is needed to stop Zsh from expanding variables and interpreting special characters before the glob runs. Zsh runs the code once per matched file, with the file name in the $REPLY variable, and keeps the file if the code exits successfully (status 0).
The + syntax is simpler, as it takes just a command name to run, which is most usefully a Zsh function, as seen below.
Using e to check for .git
I’ll show you with an example. Say I have a bunch of my open source repositories in a directory, along with some other stuff:
$ print -l *
apig-wsgi
blacken-docs
djade
random-ideas
scratch
README.md
(Using print -l rather than ls to display the raw glob without any extra recursion or formatting.)
I can filter the file list to just those with a .git directory using:
$ print -l -- *(/e:'[[ -e $REPLY/.git ]]':)
apig-wsgi
blacken-docs
djade
Let’s break down the glob there:
*matches every file in the current directory./is a built-in qualifier that limits matches to directories.e:'[[ -e $REPLY/.git ]]':runs the conditional expression[[ -e $REPLY/.git ]]for each matched directory, keeping only those containing a.gitentry.
Using + to check for a master branch
The + form can be more convenient as it lets us put our code without quoting in a regular Zsh function first, rather than cluttering the glob syntax.
As an example, let’s list Git repositories where there is still a master branch, rather than a main one:
$ has_master() { git -C $REPLY show-ref --quiet refs/heads/master 2>/dev/null }
$ print -rl -- *(/+has_master)
blacken-docs
djade
The function uses git show-ref to check whether the branch exists, with stderr redirected to hide “not a git repository” errors from the non-repository directories.
Two projects to migrate, found in one line.
😸😸😸 Check out my new book on using GitHub effectively, Boost Your GitHub DX! 😸😸😸
One summary email a week, no spam, I pinky promise.
Related posts:
- Zsh: select generated files with
(om[1])glob qualifiers - Zsh: list recently modified files with
(m0)glob qualifiers
Tags: zsh