Recursively removing the content of a directory but not a directory itself [duplicate]

I have a directory which contains other directories and files of unknown depth. How can I delete only the content of the directory — nested directories and files — but not directory itself?

I’ve tried these and they didn’t work – nothing was deleted:

rm -rf my_dir/*/*
rm -rf my_dir/**
rm -rf my_dir/*

# and
cd my_dir
rm -rf */*

How to do that?

Answer

Use find. Read the manual carefully to understand the various options and test it before you do this.

Here’s a quick example using mindepth. Note: if you have a very deep tree and lots of files find can be slow and cause file system issues and high load (depending on the file system and settings). Please beware of the impact of long running find commands. There are ways to making find faster and efficient so read up on those.

Example:
Here’s the structure I created

# tree my_dir/
my_dir/
|-- file
|-- my_dir2
|   `-- file2
`-- my_dir3
    `-- file3

Then we call find. First, I am using print instead of rm to make sure what I get is what I want. This lists just the directory, you can remove the type to see everything or add -type file.

# find my_dir -mindepth 1 -type d -print
my_dir/my_dir3
my_dir/my_dir2

Then apply recursive remove (I used verbose for testing here):

#find my_dir -mindepth 1 -type d -exec rm -rv {} \;
removed `my_dir/my_dir3/file3'
removed directory: `my_dir/my_dir3'
find: `my_dir/my_dir3': No such file or directory
removed `my_dir/my_dir2/file2'
removed directory: `my_dir/my_dir2'
find: `my_dir/my_dir2': No such file or directory

You will get the “No such file error” here as find sorts the directory list first to do a recursive search. You can suppress this error message if needed.

Check the tree now:

# tree ascii my_dir/
my_dir/
`-- file
0 directories, 1 file

Because we said type -d and recursive remove it did not remove the file in the first level. So we run:

# find my_dir -mindepth 1 -type f -exec rm -rv {} \;
removed `my_dir/file'

You can do this in one command to save time but test it. Now check again:

#tree my_dir
0 directories, 0 files

This could be improved and made more elegant but I hope this gives you an idea.

Attribution
Source : Link , Question Author : Raj , Answer Author : HBruijn

Leave a Comment