76

Is there a command to remove all files and subdirectories in a directory without deleting the directory?

For example if I have directory dontDeleteMe with subdirectories 1, 2, 3 and each subdirectory has a few pictures in it, how can I remove the subdirectories 1, 2, and 3 and all the files in the them, without removing the parent directory dontDeleteMe?

12 Answers 12

88

To remove everything in a directory without removing the directory, type in:

rm -rfv dontDeleteMe/*

Please note, the /* part is very important. If you put a space before the *, it will delete all your files in your current directory.

Also, be very careful playing with rm, -r and * all in the same command. They can be a disastrous combination.

Update: Okay, I realized if you do have hidden/dot files [filenames with dots at the beginning, e.x. .hidden] then this will leave those files intact.

So really, the simplest solution to the original question is:

rm -rfv dontDeleteMe && mkdir dontDeleteMe

Another one would be to use find's -exec option or pipe to xargs (below):

find dontDeleteMe/* -print0  | xargs -0  rm -rv
6
  • Can you give an example of using xargs? What is xargs?
    – justingrif
    Nov 1, 2011 at 18:55
  • @justingrif: find dontDeleteMe/* -print0 | xargs -0 rm -rv I believe in most cases this will work, regardless of spaces, and what not. But cd to /tmp/ and make a test directory and try it out. :)
    – Matt
    Nov 1, 2011 at 22:42
  • 5
    Re-making a directory does not equal deleting its contents. e.g. umask directory permission differences, owner differences, etc... enzotib's answer would solve the issues with your original syntax
    – user234837
    Oct 9, 2014 at 20:43
  • 5
    This is not a good answer. Using * is dangerous, and won't work on dotfiles without "dotglob" (see below). rm -rf dontDeleteMe && mkdir dontDeleteMe doesn't ensure that the dir is re-created with the same permissions/owner(s). Instead, use one of the find dontDeleteMe/ -mindepth 1 -delete variants below. Jan 15, 2015 at 13:31
  • 1
    @NilsToedtmann, with all due respect, I did give fair warning in my answer that the * should be used with care.
    – Matt
    Feb 10, 2015 at 21:34
41

Open terminal (Ctrl+Alt+T) ant type this:

find somedir -mindepth 1 -delete

This will match all files and directories within somedir and its (grand-)children including "hidden" dot files but excluding somedir itself because of -mindepth 1, then -delete them.

2
  • This works well for me, although is it fundamentally safer than using "rm -rf"?
    – Eric P
    May 25 at 8:59
  • 1
    @EricP The main difference between find with -mindepth 1 and rm is that the former will keep the directory and only delete its contents. It's not safer per se, both will delete everything in the directory without confirmation if you have the permissions to do so. But find is more flexible (it has many more options than rm). Jun 7 at 13:51
31

The only reason rm -r ./* do not always work is because you can have hidden files and/or folder that are not matched by *.

To this end, bash provide an option to make * match everything, even hidden objects:

cd dont-delete-me
shopt -s dotglob
rm -r ./*

It can be useful to reset dotglob to its default (unset) state, if you keep on using the shell where you executed the above commands:

shopt -u dotglob 
1
  • It can also not work when you have a large number of files
    – S..
    Jan 29, 2016 at 19:04
6
find /dontDeleteMe/ -xdev -depth -mindepth 1 -exec rm -Rf {} \;

Use xdev option to delete files only within device boundary.

1
  • 2
    GNU find has -delete. It implies -depth and is easier to remember than -depth -exec rm -Rf {} \; Jan 15, 2015 at 13:38
4

To delete (in terminal) all files and subdirectories except for the base directory named "dontdelete":

rm -rf dontdelete/*
1
  • 1
    This doesn't delete hidden files, so "all files" might be too bold a statement. Jul 25, 2015 at 15:55
4

You can use find with the -delete flag:

find dontDeleteMe/* -delete

The /* is important as it tells find to search only INSIDE the folder called "dontDeleteMe".

Also ensure that the -delete flag is at the end of the find command.

1
  • 3
    This solution doesn't delete any hidden files, unless you enable dotglob. Otherwise, using the -mindepth 1 flag option seems the only way to get it working. Jul 25, 2015 at 15:59
3
rm -rf  directory/{.*,/*}

What says:

Remove all files starting with . in "directory" and all other files too.

Though as kindly noted by Neftas this solution is not safe!

Safer solution is:

 rm -rf directory/!(.|..)
4
  • 1
    This command could potentially be dangerous, since you're also including . and .. directories. This may be avoided by changing {.*} to {.??*}, but then you won't delete hidden files with only one character, such as .a. Jul 25, 2015 at 12:13
  • what's about this? rm -rf directory/!(.|..)
    – Tebe
    Jul 25, 2015 at 12:38
  • That looks like a much better solution than what I came up with. May I suggest you edit your answer? Jul 25, 2015 at 12:49
  • suggestion accepted )
    – Tebe
    Jul 25, 2015 at 12:55
2

There is an even simpler answer:

  1. cd dontDeleteMe

  2. rm -rf *

Basic system administration lecture time: Be sure to pay attention to where you are when you use sweeping commands like this.

I can't say that enough. I've had to recover a box because someone wasn't paying attention and typed in rm -rf * while in /.

*nix assumes that if you are root or if you are sudo-ing as root that you know what you are doing. So make sure that you know what you're doing before you do it.

An alternative which makes sure your 'cd' command works before you issue the 'rm' is to use

cd dontDeleteMe && rm -rf *
5
  • 6
    This is a dangerous suggestion. What you want is: cd dontDeleteMe && rm -rf *
    – Izkata
    Oct 26, 2011 at 20:32
  • 1
    @Izkata Or make sure to check that the cd operation was successful, before issuing the rm command. Nov 1, 2011 at 17:42
  • 1
    @EliahKagan That's exactly what my code snippet does...
    – Izkata
    Nov 1, 2011 at 18:00
  • 1
    Actually it's not any more or any less dangerous than what you suggest. All the && does is to chain the two commands together so that they execute at the same time. If anything my method is actually SAFER since you have to stop and .look before you execute the rm -rf *. Pausing to double check is always better.
    – user30619
    Nov 4, 2011 at 13:57
  • 6
    @user30619 The && operator doesn't just chain the commands together; it requires that each command be successful before the next one will be executed. If the cd command fails for any reason (directory doesn't exist, privileges, etc) then the rm command won't be executed. I'd call that safer.
    – ean5533
    Nov 9, 2011 at 19:14
1

I am not sure why this is so complex, help me if i am wrong

cd DoNotDeleteDir #<- this is just to make sure we are inside
find . | xargs rm -rf

That's it

2
  • This has the slight flaw of trying to delete the current directory as well, which, of course, doesn't work, because it's still in use as the working directory of the invoking shell. Sep 15, 2015 at 13:26
  • One can delete the current directory from inside it--and then be "in" a nonexistent directory. rmdir ../tmp, from an empty directory called tmp, will do that. The technique in this answer doesn't delete the current directory because the rm command special-cases the specific pathnames . and .., refusing to operate on them. Thus rm: refusing to remove '.' or '..' directory: skipping '.' (from GNU rm, which provides /bin/rm in Ubuntu) is quite literally what is happening. rmdir . behaves similarly, though it shows a less illuminating Invalid argument error. @DavidFoerster Jun 2, 2020 at 2:24
0
  1. Easiest thing for me - a windows expert but an ubuntu newbie
  2. Click the Files icon on the launcher
  3. Navigate to the directory where the files and folders are located that you want to delete
  4. Right Click in a blank area of the window next to the files and click "Open in Terminal" - leave the Files window open
  5. A terminal window will open and will be "set" to the folder you located
  6. You can type "dir" (disregard quotes when i say type) and press enter for the terminal to show a list of files and folders - just to prove you are "in" the right folder
  7. type "rm -rf *" and press enter
  8. depending on size of folders/files to delete system will pause
  9. When terminal prompt returns, the Files window you had opened will now say "Folder is Empty"
  10. I had success with this method and it gave me comfort to see the files/folder both in the Files window and as a result of the Dir command in the terminal window
  11. I was also comforted that the Files window displayed the folder now empty - especially since I had been chasing these files around looking for the trash folder that they were in
  12. Thanks to everyone else who submitted answers - it was very informative
1
  • 1
    That seems quite convoluted – especially since you're going to end up running rm -rf * anyway. Nov 9, 2016 at 0:46
0
rm -rf ${PWD}/*

will clear the present working directory

0

I would use find as suggested by guciek's answer, and add -xdev to make sure it doesn't descend into other filesystems:

find 'dontDeleteMe' -xdev -mindepth 1 -deletea

(I added quotes in case the real path contains spaces)

An alternative with Bash and rm could be

rm -rf 'dontDeleteMe'/{*,.[!.]*}

This would also remove hidden files, without producing errors. See this answer for details.

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.