ZSH: Recursive globbing excluding specified hidden directories
The easiest way to make a glob pattern match dot files is to use the D
glob qualifier.
**/*(D)
The precedence of ~
is lower than /
, so **~.hg/*
is **
minus the matches for .hg/*
. But **
is only special if it's before a /
, so here it matches the files in the current directory. To exclude .hg
and its contents, you need
**/*~.hg~.hg/*(D)
Note that zsh will still traverse the .hg
directory, which can take some time; this is a limitation of **
: you can't set an exclusion list directly at this level.
**/*(D)
(short for (*/)#*(D)
) includes dotfiles and dotdirs as already said.
If you want to exclude .hg
directories at every level, you need:
(^.hg/)#^.hg(D)
(you need setopt extendedglob
for the ^
and #
operators)
As already said, the ~pattern
will exclude entries (based on whether their full expansion matches "pattern" after the list has been generated, so will not stop it to descend into subdirs).