72

Say I have a directory named foo/. This folder includes subdirectories. How can I delete all the empty directories in one command?

hsnee
  • 145
  • 1
  • 1
  • 7
justingrif
  • 10,850
  • 5
  • 21
  • 19

5 Answers5

150

Try this command:

find . -empty -type d -delete

The find command is used to search for files/directories matching a particular search criteria from the specified path, in this case the current directory (hence the .).

The -empty option holds true for any file and directory that is empty.

The -type d option holds true for the file type specified; in this case d stands for the file type directory.

The -delete option is the action to perform, and holds true for all files found in the search.

Bill
  • 1,814
  • 2
  • 17
  • 16
  • I think this is the easiest way to do it so I am going to go ahead and mark this as answered. – justingrif Oct 30 '11 at 03:24
  • Hey Bill, I tried to post another similiar question and it wouldn't let me because it said it was a dupe, so I was hoping you might be able to answer me here. Say I wanted to do the same thing as above but remove all directories whether they are empty or not. – justingrif Nov 03 '11 at 19:39
  • 4
    The way you would remove directories, regardless of whether or not they are empty, type the following command: `rm -rf `. This will remove the directory, along with all its contents including files and subdirectories. The `-r` option means delete recursively, while the `-f` command means don't prompt before deleting. If you want to be prompted before deleting a directory/file, however, replace the `-f` option with the `-i` option. – Bill Nov 03 '11 at 23:24
  • What if there were some files in said directory I wanted to keep. So, I wanted to delete all directories in /foo/bar/ but keep any files that might be in there. – justingrif Nov 04 '11 at 03:23
  • 2
    It is possible to do this by using a pipe to feed the `stdout` of one command (e.g. `find`) into the `stdin` of the other (e.g. `rm`), however, be very careful since it may wipe out or delete files/directories that you don't want to delete! For further information on how to do this, see the `man` pages for each of these commands. To be safe, always test such things in a temporary directory before trying out on the real thing. – Bill Nov 04 '11 at 04:55
  • doesn't work in mac, only deletes the leaf empty directories, not the ones that contained only empty directories. – Joey Baruch Oct 26 '17 at 11:05
  • 1
    @joeybaruch On MacOS almost every directory you "visited" with Finder.app contains a `.DS_Store` hidden file, that usually stores your sorting/viewing preferences for that directory. Other apps may add other hidden files (e.g. Adobe Bridge may add a `.BridgeLabelsAndRatings` file), so perhaps those directories aren't really empty. Anyways, you can remove the `.DS_Store` file with `find . -name '.DS_Store' -delete` and then try again to remove the empty directories with the suggested command. – gerlos Feb 22 '18 at 13:09
  • With the `-depth` option `find` can even match and delete directories that only become empty because all of their (empty) subdirectories were deleted. Try it out with `mkdir -p a/b/c/d && find a -depth -type d -empty -print -delete`. – David Foerster Feb 22 '18 at 13:49
14

You can take advantage of the rmdir command's refusal to delete non-empty directories, and the find -depth option to traverse the directory tree bottom-up:

find . -depth -exec rmdir {} \;  

(and ignore the errors), or append 2>/dev/null to really ignore them.

The -depth option to find starts finding at the bottom of the directory tree.

rm -rf will delete all the files in the directory (and its subdirectories, and ....) AND all the directories and everything.

dessert
  • 39,392
  • 12
  • 115
  • 163
waltinator
  • 35,099
  • 19
  • 57
  • 93
8
rmdir *

Will delete all empty directories. It'll throw up an error for every non-empty directory and file, to stop those errors from cluttering your terminal, use

rmdir * 2> /dev/null
evilsoup
  • 4,435
  • 1
  • 19
  • 26
3
find . -type d -empty -delete -maxdepth 1

For if you only want to delete the direct subdirectories of foo/.

Simon Baars
  • 131
  • 6
0

Python approach

$ tree                                                                                                                                                                                  
.
├── empty_dir1
├── empty_dir2
├── subdir1
│   ├── file1.abc
│   └── file2.abc
└── subdir2
    ├── file1.abc
    └── file2.abc

4 directories, 4 files
$ python -c 'import os;empty=[r for r,s,f in os.walk(".") if not f and not s and r != "." ];map(lambda x: os.rmdir(x),empty)'
$ tree
.
├── subdir1
│   ├── file1.abc
│   └── file2.abc
└── subdir2
    ├── file1.abc
    └── file2.abc

This works like so:

  • we use os.walk() function to walk recursively the directory tree. On each iteration r is set to current folder that we're accessing,s contains list of directories within r, and f will contain list of files in that folder. Of course if f and s are empty, we know that r is empty.
  • first list-comprehension allows us to create empty , the list of all directories that are empty, based on the evaluation stated above.
  • second function, map() is used to perform os.rmdir() on each item in empty list. List comprehension could be used as well as alternative.

As a script this would be as so:

#!/usr/bin/env python
import os
empty=[]
for r,s,f in os.walk("."):
    if not f and not s and r != ".":
        empty.append(r)

for i in empty:
    os.rmdir(i)
Sergiy Kolodyazhnyy
  • 103,293
  • 19
  • 273
  • 492
  • too complicated for simply questions :( – nurulhudamustaqim Feb 17 '19 at 06:21
  • @nurulhudamustaqim Depends on point of view. For a lot of Linux users who are used to Python this is actually very modest :) And besides its variety. Modern system administration is not limited to bash or `/bin/sh` only and Python is actually more elegant language than those two – Sergiy Kolodyazhnyy Feb 17 '19 at 06:24