I'm trying to write some ruby that would recursively search a given directory for all empty child directories and remove them.
Thoughts?
Note: I'd like a script version if possible. This is both a practical need and a something to help me learn.
I'm trying to write some ruby that would recursively search a given directory for all empty child directories and remove them.
Thoughts?
Note: I'd like a script version if possible. This is both a practical need and a something to help me learn.
Why not just use shell?
find . -type d -empty -exec rmdir '{}' \;
Does exactly what you want.
In ruby:
Dir['**/*'] \
.select { |d| File.directory? d } \
.select { |d| (Dir.entries(d) - %w[ . .. ]).empty? } \
.each { |d| Dir.rmdir d }
Dir.glob('**/*').each do |dir|
begin
Dir.rmdir dir if File.directory?(dir)
# rescue # this can be dangereous unless used cautiously
rescue Errno::ENOTEMPTY
end
end
I've tested this script on OS X, but if you are on Windows, you'll need to make changes.
You can find the files in a directory, including hidden files, with Dir#entries.
This code will delete directories which become empty once you've deleted any sub-directories.
def entries(dir)
Dir.entries(dir) - [".", ".."]
end
def recursively_delete_empty(dir)
subdirs = entries(dir).map { |f| File.join(dir, f) }.select { |f| File.directory? f }
subdirs.each do |subdir|
recursively_delete_empty subdir
end
if entries(dir).empty?
puts "deleting #{dir}"
Dir.rmdir dir
end
end
module MyExtensions
module FileUtils
# Gracefully delete dirs that are empty (or contain empty children).
def rmdir_empty(*dirs)
dirs.each do |dir|
begin
ndel = Dir.glob("#{dir}/**/", File::FNM_DOTMATCH).count do |d|
begin; Dir.rmdir d; rescue SystemCallError; end
end
end while ndel > 0
end
end
end
module ::FileUtils
extend FileUtils
end
end