Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Say I have the following files:

|-- bar
`-- foo
    |-- type_A_1
    |-- type_A_2
    |-- type_B_1
    |-- type_B_2
    |-- type_B_xx
    |-- type_B_xx
    `-- something_else

I thought the following command

print -l foo/*~{type_B*}

would print everything under foo except things that start with type_B but it doesn't, instead it prints everything under foo:


I also tried print -l foo/*~type_B and got the same thing.

How does the exception wildcard ~ work in zsh?

share|improve this question
up vote 6 down vote accepted

You need to include the directory into the exception: print -l foo/*~foo/type_A* or print -l foo/*~{foo/type_A*}.

If you want, you can replace the directory by a wildcard: print -l foo/*~*/type_A*

share|improve this answer
Thanks! About the second pattern, do you mind explaining how the pattern foo/*~*/type_A* works? Does the second * expand to every folder under the working directory, or is it smart enough to only expand to foo? – Amelio Vazquez-Reina Feb 22 '12 at 16:26
@roseck Because it seems really fast (for example when you run print *~**/* in the / directory), I assume that it first expand the first pattern and then remove all matches which fit to the exclusion pattern. – jofel Feb 22 '12 at 16:36
@roseck ~ is purely textual, the part before the ~ expands as it always would, then the part after strips away matches. ​@jofel A better test would be print /**/*~*: you can observe that it traverses the whole tree, even if it ends up printing nothing. – Gilles Feb 22 '12 at 23:43

zsh has the ^ glob operator when EXTENDED_GLOB is on. It seems like the perfect fit for your stated situation:

setopt extendedglob
print -l foo/^type_A*

It means “match anything, except what matches the following pattern”, but its effect is limited to the portion of the pattern between slashes, or between the beginning of the pattern and the first slash, or (as in this case) between the last slash and the end of the pattern.

You can view the zsh options currently enabled with:


And disable EXTENDED_GLOB with:

unsetopt extendedglob
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.