Ruby: how do I recursively find and remove empty directories?
You have to delete in reverse order, otherwise if you have an empty directory foo with a subdirectory bar you will delete bar, but not foo.
Dir.glob(dir + "/**/*").select { |d|
File.directory?(d)
}.reverse_each { |d|
if ((Dir.entries(d) - %w[ . .. ]).empty?)
Dir.rmdir(d)
end
}
In ruby:
Dir['**/*'] \
.select { |d| File.directory? d } \
.select { |d| (Dir.entries(d) - %w[ . .. ]).empty? } \
.each { |d| Dir.rmdir d }
Looking at the examples from kch, dB. and Vishnu above, I've put together a one-liner that I think is a more elegant solution:
Dir['**/'].reverse_each { |d| Dir.rmdir d if Dir.entries(d).size == 2 }
I use '**/'
instead of '/**/*'
for the glob, which only returns directories, so I don't have to test whether it's a directory later. I'm using reverse_each
instead of sort.reverse.each
as it's shorter and supposedly more efficient, according to this post. I prefer Dir.entries(d).size == 2
to (Dir.entries(d) - %w[ . .. ]).empty?
because it's a little easier to read and understand, although (Dir.entries(d) - %w[ . .. ]).empty?
would probably work better if you had to run your script on Windows.
I've tested this quite a bit on Mac OS X and it works well, even with recursive empty directories.