Given this directory content :


in bash, when I enter

rm *.file !(two)

only one.file and three.file are deleted. How can I do this in ZSH?

  • 3
    In fact, you need to use rm !(two).file in bash.
    – choroba
    Jun 27, 2014 at 15:17

2 Answers 2


I was interested in the answer too, and a quick search turned up this article on globbing in zsh. The highlights:

  • ^ Acts as a negation. For example, ls ^two.file will only list the one.file and three.file.
  • You can combine ^ and *. For example, ls ^two* will list anything that doesn't start with "two"
  • You can use parentheses to make more complex matches. For example, ls (^two).file will list anything that doesn't start with "two", and does end in "file".
  • 7
    Enable extended globbing first: setopt extended_glob
    – Emre
    Sep 19, 2015 at 1:12
  • @Emre Thanks a lot, that was the one info that took me 2 hours to find Nov 22, 2015 at 1:33
  • @LukasJuhrich lol, you're not alone. Jun 18, 2022 at 10:37

If you want to use the ksh syntax ls !(two).file, simply turn on the KSH_GLOB option in zsh:

$ setopt KSH_GLOB
$ ls -1 !(two).file

But zsh provides other powerful globbing techniques, activated by the EXTENDED_GLOB option. For a complete list, please read the section FILENAME GENERATION in man zshexpn. Most relevant to the question are these operators:

  • ^x matches anything except the pattern x, so in your case ls -1 ^two.file
  • x~y is more powerful as it matches anything that matches the pattern x but does not match y, so ls -1 *~two.file. The special thing is, that you have can use another globbing pattern for x, e.g.

    $ ls -1 *.file~two*

    This is not possible with the ^ operator, which is in this case equivalent to *~:

    $ ls -1 *.file^two*

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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