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).

Tags:

Zsh

Wildcards