Tell me more ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Suppose I have a dir tree like this:

ROOTDIR
    └--SUBDIR1
        └----SUBDIR2
            └----SUBDIR3

I am looking for a command such that when I input:

$ [unknown command] ROOTDIR

The whole dir tree can be deleted if there is no file but only dirs inside the whole tree. However, say if there is a file called hello.pdf under SUBDIR1:

ROOTDIR
    └--SUBDIR1
        └--hello.pdf
        └----SUBDIR2
            └----SUBDIR3

Then the command must only delete SUBDIR2 and below.

share|improve this question

migrated from stackoverflow.com Nov 7 '11 at 22:00

6 Answers

up vote 4 down vote accepted

Alexis is close. What you need to do is this:

find . -type d -depth -empty -exec rmdir "{}" \;

That will first drill down the directory tree until it finds the first empty directory, then delete it. Thus making the parent directory empty which will then be deleted, etc. This will produce the desired effect (I do this probably 10 times a week, so I'm pretty sure it's right). :-)

share|improve this answer
Why is -depth option necessary? find . -type d -empty -exec rmdir "{}" \; should also work.... right? – greenmang0 Nov 8 '11 at 14:26
1  
Consider if you have a tree (directories only) foo/bar/baz. Unless you use -depth, it will try to delete foo first, fail, and you'll end up with foo/bar after running. – l0b0 Nov 8 '11 at 14:43

I would try this:

find ROOTDIR -type d -depth -exec rmdir {} \;
share|improve this answer
find ROOTDIR -type d -empty -delete

same as

find ROOTDIR -type d -depth -empty -exec rmdir "{}" \;

but uses the built in "-delete" action.

Note that "-delete" implies "-depth".

share|improve this answer
rmdir $(find ROOTDIR -type d | sort -r)
share|improve this answer
Tested and worked, thanks =) – gsklee Nov 7 '11 at 21:12
3  
This won't work if any of the directory names contains whitespace or globbing characters. It's generally a bad idea to use command substitution on a list of file names. It's especially a bad idea with find because find has a way to do the processing cleanly: find … -exec. – Gilles Nov 7 '11 at 23:01
Thanks to Gilles for pointing that out. @lanzz, usually posting just a command without explaining what it does (and in this case, the pitfalls) is not enough. Please add to your answer. – MaxMackie Nov 8 '11 at 3:06

I would do this:

find ROOTDIR -type d | xargs -0 -I {} rmdir {}
share|improve this answer

Here are some requirements before we can do it safely:

  1. remove subdirectories first and then upper level directories, i.e. we need to sort directory listing or use rmdir --parents flag
  2. start ROOTDIR always with / or ./ to avoid surprises with files beginning with -
  3. use NUL terminated list of directories to work with directory names with spaces

Here is how I'd do that in shell:

find ./ROOTDIR -type d | sort -r | tr '\n' '\000' | xargs -0 rmdir --ignore-fail-on-non-empty

If you don't mind some redundant errors then you can just force removing all directories with parents and you don't need to do any sorting (you can't sort NUL terminated strings which adds need to tr)

find ./ROOTDIR -type d -print0 | xargs -0 rmdir --ignore-fail-on-non-empty --parents
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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