How do I recursively remove subdirectories and files, but not the first parent directory?

I'm able to use the following to remove the target directory and recursively all of its subdirectories and contents.

find '/target/directory/' -type d -name '*' -print0 | xargs -0 rm -rf

However, I do not want the target directory to be removed. How can I remove just the files in the target, the subdirectories, and their contents?

4 Answers

The previous answer is almost correct. However, you shouldn't quote the shell glob characters if you want them to work. So, this is the command you're looking for:

rm -rf "/target/directory with spaces/"*

Note that the * is outside of the double quotes. This form would also work:

rm -rf /target/directory\ with\ spaces/*

If you have the * in quotes as shown above, then it will only attempt to remove the single file literally named * inside the target directory.

1

Three more options.

  1. Use find with -mindepth 1 and -delete:

    −mindepth levels
    Do not apply any tests or actions at levels less than levels (a non‐negative integer).
    −mindepth 1 means process all files except the command line arguments.

    -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.
    Test carefully with the -depth option before using this option.

    # optimal?
    # -xdev don't follow links to other filesystems
    find '/target/dir with spaces/' -xdev -mindepth 1 -delete
    # Sergey's version
    # -xdev don't follow links to other filesystems
    # -depth process depth-first not breadth-first
    find '/target/dir with spaces/' -xdev -depth -mindepth1 -exec rm -rf {} \;

2. Use find, but with files, not directories. This avoids the need to rm -rf:

 # delete all the files; find '/target/dir with spaces/' -type f -exec rm {} \; # then get all the dirs but parent find '/target/dir with spaces/' -mindepth 1 -depth -type d -exec rmdir {} \; # near-equivalent, slightly easier for new users to remember find '/target/dir with spaces/' -type f -print0 | xargs -0 rm find '/target/dir with spaces/' -mindepth 1 -depth -type d -print0 | xargs -0 rmdir

3. Go ahead and remove the parent directory, but recreate it. You could create a bash function to do this with one command; here's a simple one-liner:

 rm -rf '/target/dir with spaces' ; mkdir '/target/dir with spaces'

How about

rm -rf /target/directory\ path/*

If there may be files starting with . in the target directory.

rm -rf "/target/directory path/*" "/target/directory path/.??*"

This second will match everything starting with a ., except . and .. It will fail on names like .a, but that isn't very common. It could be tweaked if necessary to cover all of the cases.

6
find /target/directory/ -xdev -depth -mindepth 1 -exec rm -Rf {} \;

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

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

You Might Also Like