270

Possible Duplicate:
How to remove all empty directories in a subtree?

I create directories very often, scattered over my home directory, and I find it very hard to locate and delete them.

I want any alias/function/script to find/locate and delete all empty directories in my home directory.

2
  • 5
    This does not answer your question, but could solve the underlying problem. I often use the construct: WORK=$(mktemp -d) or cd $(mktemp -d). Of course don't put important files that you need to preserve in those directories. But most likely your system is already setup to automagically make those files disappear after a while.
    – emory
    Aug 25, 2012 at 23:35
  • I have my machine mount a tmpfs ram drive to the /z/ directory on start-up and do all my temporary work there.
    – Richard
    Oct 21, 2013 at 20:23

2 Answers 2

506

The find command is the primary tool for recursive file system operations. Use the -type d expression to tell find you're interested in finding directories only (and not plain files). The GNU version of find supports the -empty test, so

$ find . -type d -empty -print

will print all empty directories below your current directory.

Use find ~ -… or find "$HOME" -… to base the search on your home directory (if it isn't your current directory).

After you've verified that this is selecting the correct directories, use -delete to delete all matches:

$ find . -type d -empty -delete
13
  • 7
    Good solution, but it should be noted that not all version of find have -empty.
    – jordanm
    Aug 25, 2012 at 21:49
  • @Baldrick Doesn't looks from home directory if I run it form ~/Desktop. Aug 25, 2012 at 21:58
  • @Santosh: The command as it is, is meant to be run from your home directory (that's why I added ~$ in the beginning). If you want to run it regardless of your working directory, use "$HOME" instead of . as jordanm suggested in his answer.
    – Baldrick
    Aug 25, 2012 at 22:09
  • 4
    Consider changing the second example to . instead of ~. If somebody copy-pastes this without noticing and only checks the output of the first this can have bad consequences. Jun 3, 2016 at 1:28
  • 4
    I would add -mindepth 1 here, to prevent from deleting the starting directory itself, if it would be empty. It's not really probable case for $HOME but if you would use this on any other directory.. Aug 20, 2016 at 12:46
24

You can call rmdir on every directory, since rmdir will only delete a directory if it is empty:

find "$HOME" -type d -exec rmdir {} + 2>/dev/null

If you also want to print the directories being removed, you will need to check if they are empty:

find "$HOME" -type d -exec bash -c 'shopt -s nullglob; shopt -s dotglob; files=("$1"/*); [[ ${files[@]} ]] || rmdir -v "$1"' -- {} \; 

Here is a pure bash example (version 4 or higher):

shopt -s globstar
for dir in **/; do
   files=("$dir"/*)
   [[ ${files[@]} ]] || rmdir -v "$dir"
done
5
  • And what if I only want to find/locate and not delete? Aug 25, 2012 at 21:44
  • @Santosh - In either of the last two examples, just change rmdir -v to echo.
    – jordanm
    Aug 25, 2012 at 21:47
  • 7
    BusyBox find doesn't have -empty, so the -exec trick is helpful. But rather than sending errors off to /dev/null, it's better to tell rmdir to suppress them, e.g. find . -type d -depth -exec rmdir -p --ignore-fail-on-non-empty {} \; Apr 1, 2015 at 19:19
  • 1
    These commands have terrible performance since they create a new process for every directory found. When using that approach, you really should at least use something like find ... | xargs -n 100 rmdir to delete them in batches. Even then, it won't work properly because it will fail to remove early directories that will later become empty because of later empty directories' removal. Thus you'd need to execute it several times.
    – jlh
    Nov 13, 2015 at 13:25
  • 4
    @jlh No, the first command will only execute rmdir once. That's the difference between using + and \; for terminating a command in find.
    – jordanm
    Nov 13, 2015 at 14:10

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