ZSH – Recursive Globbing Excluding Specified Hidden Directories

wildcardszsh

I thought the glob pattern:

**/(*|.*)

would represent every folder and file starting with dot (.) or not, but it skips directories in the current directory that start with ..

What is the glob pattern that means:

every file and folder that may or may not start with . on the
current and deeper folders

Also: How can I exclude a specific folder (or even better, a glob subpattern) from a recursive glob pattern such as the one above?

I have tried the following to exclude the folder .hg from the current level (but include other folders starting with the . character):

**~.hg/*

but it didn't go recursively into deeper directories.

Best Answer

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.

Related Question