What is the command to remove all files but not directories?
18,599
Solution 1
What you're trying to do is recursive deletion. For that you need a recursive tool, such as find
.
find FOLDER -type f -delete
Solution 2
With bash
:
shopt -s globstar ## Enables recursive globbing
for f in FOLDER/**/*; do [[ -f $f ]] && echo rm -- "$f"; done
Here iterating over the glob expanded filenames, and removing only files.
The above is dry-run, if satisfied with the changes to be made, remove echo
for actual removal:
for f in FOLDER/**/*; do [[ -f $f ]] && rm -- "$f"; done
Finally, unset globstar
:
shopt -u globstar
With zsh
, leveraging glob qualifier:
echo -- FOLDER/**/*(.)
(.)
is glob qualifier, that limits the glob expansions to just regular files.
The above will just print the file names, for actual removal:
rm -- FOLDER/**/*(.)
Related videos on Youtube
Author by
PKM
Updated on September 18, 2022Comments
-
PKM almost 2 years
Let's say I have a directory tree like this:
FOLDER: file1 file2 file3 Subfolder1: file1 file2 Subfolder2: file1 file2
If I used
rm -r FOLDER/*
, everything in FOLDER would be deleted including sub-directories. How can I delete all files in FOLDER and in its sub-directories without deleting actual directories? -
Admin over 7 years
-exec rm {} +
would be faster, especially if there are lots of files. -
Admin over 7 yearsAnd
find . ! -type d -exec rm {} +
removes sym links as well. -
Admin over 7 years@muru: If a particular implementation of
find
doesn't support-delete
it probably doesn't support-exec ... {} +
either. The recommended way to deal with that isfind ... -print0 | xargs -r0 rm
(if one expects many potential matches). -
marcelm over 7 years+1 for zsh globbing. More people should be aware of the awesome things zsh can do.
-
Admin over 7 years@DavidFoerster not really.
-exec ... {} +
is POSIX, but-delete
isn't. (Neither is-print0
, by the way.) -
Admin over 7 years@muru: Fair enough. I've encountered at least two non-POSIX
find
implementations that supported-print0
but not-exec ... {} +
(I don't remember about-delete
though). One was on OS X, the other on Solaris (a few years ago on a very conservatively updated system). You can also substitute-print0
with-printf '%p\0'
. Anyway, this is AskUbuntu and not Unix & Linux and Ubuntu uses GNU find since forever. -
Admin over 7 yearsOne that is even faster due to not forking for every rm: find . ! -type d -print0|xargs -0 -n50 rm -f . That will delete 50 filenames at a time, and delimit with \0 just in case some filenames have spaces or other characters.