Given this directory content :
one.file two.file three.file
in bash, when I enter
rm *.file !(two)
three.file are deleted. How can I do this in ZSH?
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.filewill only list the one.file and three.file.
*. For example,
ls ^two*will list anything that doesn't start with "two"
ls (^two).filewill list anything that doesn't start with "two", and does end in "file".
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 one.file three.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:
^xmatches 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* one.file three.file
This is not possible with the
^ operator, which is in this case equivalent to
$ ls -1 *.file^two* one.file three.file two.file