I’ve been trying to find a command to remove all files in a folder but not a kind of filetype. But I seems to not have any luck. What I’ve tried so far :
set extended_glob rm !(*.dmg) # this returns zsh:number expected rm ./^*.dmg # this returns no matches found
The version of zsh I’m using is zsh 5.0.2 (x86_64-apple-darwin13.0.1) .
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
The extended_glob option gives you zsh’s own extended glob syntax.
setopt extended_glob rm -- ^*.dmg rm -- ^*.(dmg|txt)
This removes files without an extension (e.g. README). If you want to keep those files, you can use the ~ operator to limit the matches:
setopt extended_glob rm -- *.*~*.dmg
If you want to delete files in subdirectories as well, you can use ** for recursive globbing. Pass the . glob qualifier to restrict the matching to regular files, or use ^/ instead of . to match all non-directories (including e.g. symbolic links). (Note that rm -r wouldn’t help you since it would either delete a directory and all its contents, or not descend into a directory at all.)
rm -- **/^*.(dmg|txt)(.)
You can set the ksh_glob option to get ksh globs. Beware that in the common case where the negative pattern is the last thing in the word, zsh may parse the parentheses as glob qualifiers (it doesn’t do this in ksh emulation mode).
setopt ksh_glob rm -- !(*.dmg|*.txt) setopt no_bare_glob_qual rm -- !(*.dmg)
Method 2
You can use find instead of your shell:
find . -mindepth 1 -maxdepth 1 ! -name "*.dmg" -delete
From man find:
! expr True if expr is false. This character will also usually need
protection from interpretation by the shell.
-name pattern
Base of file name (the path with the leading directories removed)
matches shell pattern pattern.
-delete
Delete files; true if removal succeeded. If the removal failed,
an error message is issued. If -delete fails, find's exit status
will be nonzero (when it eventually exits). Use of -delete
automatically turns on the -depth option.
If you can’t use find for whatever reason, here’s a way to do it with zsh (or other shells). zsh being zsh, there is probably a simpler way of doing this but since I’m a bash guy, this is what I came up with:
for file in *; do if [[ ! "$file" == *.dmg ]]; then rm $file; fi; done
Method 3
Another way to remove files is with find, xargs and rm:
find . -mindepth 1 -maxdepth 1 ! -name '*.dmg' -print0 | xargs -0 rm
Method 4
One can also use fd (git-project) or fdfind on debian systems, which has a very user-friendly interface.
The command is
fd --exclude='*.dmg' --hidden --exec rm fdfind --exclude='*.dmg' --hidden --exec rm # For Debian systems fd -E '*.dmg' -H -x rm # Short notation
Method 5
find path -mindepth 1 -maxdepth 1 -type f ! -name "*.dmg" -exec rm -vf {} ;
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0