# Deleting empty directories

**URL:** <https://www.ruby-forum.com/t/deleting-empty-directories/113228>\
**Category:** Ruby\
**Created:** [August 29, 2007, 1:11am UTC](https://www.ruby-forum.com/t/deleting-empty-directories/113228 "2007-08-29T01:11:03Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [August 29, 2007, 1:11am UTC](https://www.ruby-forum.com/t/deleting-empty-directories/113228/1 "2007-08-29T01:11:03Z")

</div>

Hello,

I’m putting together a script to automatically update a repository  
working copy. The  
scenario is such that the versioned working copy itself is not being  
modified, but I am  
simply rsync’ing changes from an unversioned source (i.e. just a bunch  
of directories),  
and then committing (and then tagging) those files. It sounds weird, I  
know, but it’s just  
temporary. Honest.

Anyway, the need has arisen to delete empty directory heirarchies (rsync  
will delete the  
files but not the directories because of the .svn subdirs). What I’ve  
done so far is this:

require ‘fileutils’

def empty\_dirs  
@current.collect do |f|  
f if (File.directory?(f) && Dir.glob("#{f}/\*").empty?)  
end.compact  
end

def remove\_empty\_dirs  
while not empty\_dirs.empty?  
empty\_dirs.each {|d| FileUtils.rm\_rf(d)}  
end  
end

where the @current contains the updated list of files in my versioned  
working copy after I  
rsync’d, but before I started comparing the changes in my working copy.  
I created a dummy  
repository with a relatively complicated heirarchy of directories to  
test the above and it  
seems to work. However, two things bug me:

Firstly, in empty\_dirs, I think

f if (File.directory?(f) && Dir.glob("#{f}/\*").empty?)

looks ugly. My limited experience is that if something looks ugly it can  
usually be  
expressed better. I haven’t used collect too much either, so its  
intricacies escape me.

Secondly, I prefer not to test for negatives, as in

while not empty\_dirs.empty?

I also would rather not have an open loop either, but if a directory  
contains empty  
subdirectories, the parent directory is not considered empty, and etc.  
etc. As you can  
probably tell, recursion is not my strong point.

Would any kind soul out there care to provide any pointers for cleaning  
up the methods above?

Thanks for any info,

cheers,

paulv

p.s. BTW, I think the remove\_empty\_dirs method still needs to remove the  
deleted  
directories from @current to prevent them being tested again in the next  
call to empty\_dirs.

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [August 29, 2007, 1:58am UTC](https://www.ruby-forum.com/t/deleting-empty-directories/113228/2 "2007-08-29T01:58:06Z")

</div>

Hi –

On Wed, 29 Aug 2007, Paul van Delst wrote:

> I’ve done so far is this:  
> while not empty\_dirs.empty?  
> Firstly, in empty\_dirs, I think
> 
> f if (File.directory?(f) && Dir.glob("#{f}/\*").empty?)
> 
> looks ugly. My limited experience is that if something looks ugly it can  
> usually be expressed better. I haven’t used collect too much either, so its  
> intricacies escape me.

You’re currently using collect plus compact, but you can actually just  
use select. (That’s not a general equivalence, but in this case it  
applies.)

@current.select do |f|  
File.directory?(f) && Dir["#{f}/\*"].empty?  
end

I’d be inclined to break things out a little. (Untested code follows  
– please test on expendable data 🙂

require ‘fileutils’

def dirs  
@current.select {|f| File.dir?(f) }  
end

def empty\_dirs  
dirs.select {|d| Dir["#{d}/\*"].empty? }  
end

def non\_empty\_dirs  
dirs - empty\_dirs  
end

def remove\_empty\_dirs  
non\_empty\_dirs.each {|d| FileUtils.rm\_rf(d) }  
end

> Secondly, I prefer not to test for negatives, as in
> 
> while not empty\_dirs.empty?

You can use until instead of while not.

> paulv
> 
> p.s. BTW, I think the remove\_empty\_dirs method still needs to remove the  
> deleted directories from @current to prevent them being tested again in the  
> next call to empty\_dirs.

Or you can reset @current before each call, or some combination. I  
haven’t done either in my sample code; I’m just assuming that @current  
is what it should be, but you’ll definitely have to factor that in.

David

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [August 29, 2007, 3:50pm UTC](https://www.ruby-forum.com/t/deleting-empty-directories/113228/3 "2007-08-29T15:50:45Z")

</div>

removed\_email\_address@domain.invalid wrote:

> Hi –
> 
> On Wed, 29 Aug 2007, Paul van Delst wrote:

[snip]

> > end
> > 
> > def remove\_empty\_dirs  
> > while not empty\_dirs.empty?  
> > empty\_dirs.each {|d| FileUtils.rm\_rf(d)}  
> > end  
> > end

[snip…asking for a better way]

> def non\_empty\_dirs  
> dirs - empty\_dirs  
> end
> 
> def remove\_empty\_dirs  
> non\_empty\_dirs.each {|d| FileUtils.rm\_rf(d) }  
> end

Hello,

Excellent! David, thanks very much. The extra reduction of tasks is  
exactly what I was  
looking for (it certainly is a skill that I am having difficulty  
mastering).

I changed the remove\_empty\_dirs to a) remove the empty, not non-empty,  
dirs (! :o), and b)  
modify the @current file list:

def remove\_empty\_dirs  
until empty\_dirs.empty?  
empty\_dirs.each do |d|  
@current.delete(d)  
FileUtils.rm\_rf(d)  
end  
end  
end

Again, thanks very much.

cheers,

paulv
