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/**/*(.)
Share:
18,599

Related videos on Youtube

PKM
Author by

PKM

Updated on September 18, 2022

Comments

  • PKM
    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
    Admin over 7 years
    -exec rm {} + would be faster, especially if there are lots of files.
  • Admin
    Admin over 7 years
    And find . ! -type d -exec rm {} + removes sym links as well.
  • Admin
    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 is find ... -print0 | xargs -r0 rm (if one expects many potential matches).
  • marcelm
    marcelm over 7 years
    +1 for zsh globbing. More people should be aware of the awesome things zsh can do.
  • Admin
    Admin over 7 years
    @DavidFoerster not really. -exec ... {} + is POSIX, but -delete isn't. (Neither is -print0, by the way.)
  • Admin
    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
    Admin over 7 years
    One 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.