回答
在红宝石:
Dir['**/*'] \
.select { |d| File.directory? d } \
.select { |d| (Dir.entries(d) - %w[ . .. ]).empty? } \
.each { |d| Dir.rmdir d }
你能解释第3行中的“ - ”吗? – 2009-08-17 22:03:37
我正在减去包含字符串的数组“。”和“..”,因为每个目录都包含这两个特殊条目。 – kch 2009-08-17 22:03:48
另外,你能解释一下“\”是什么吗?续行?他们需要吗? – 2009-08-17 22:05:21
为什么不使用shell?
找到。 -type d -empty -exec rmdir'{}'\;
完全是你想要的。
我希望得到一个ruby脚本版本来帮助你理解文件的工作。我可以从一个rake脚本中用'sh
脚本命令将完全相同。不过,下面的帖子有一个适合你的答案。 – koenigdmj 2009-08-17 22:10:00
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
我测试过的OS X这个脚本,但如果你使用的是Windows,你需要做出改变。
您可以使用Dir#条目找到包含隐藏文件的目录中的文件。
此代码将删除删除任何子目录后变为空的目录。
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
Dir['/Users/path/Movies/incompleteAnime/foom/**/*']. \
select { |d| File.directory? d }. \
sort.reverse. \
each {|d| Dir.rmdir(d) if Dir.entries(d).size == 2}
就像第一个例子,但第一个例子似乎并没有处理递归位。排序和反向确保我们首先处理最嵌套的目录。
我想sort.reverse可以写成sort {|a,b| b <=> a}
效率
你必须按相反的顺序进行删除,否则如果你有一个子目录吧,你会删除栏空目录foo的,但不是foo。
Dir.glob(dir + "/**/*").select { |d|
File.directory?(d)
}.reverse_each { |d|
if ((Dir.entries(d) - %w[ . .. ]).empty?)
Dir.rmdir(d)
end
}
查看来自kch,dB的例子。毗湿奴及以上,我已经把一个班轮,我认为是一个更优雅的解决方案:
Dir['**/'].reverse_each { |d| Dir.rmdir d if Dir.entries(d).size == 2 }
我用'**/'
,而不是'/**/*'
的水珠,它仅返回目录,所以我没有以后再测试它是否是一个目录。根据post,我使用的是reverse_each
而不是sort.reverse.each
,因为它更短并且效率更高。我更喜欢到(Dir.entries(d) - %w[ . .. ]).empty?
,因为它更容易阅读和理解,但如果必须在Windows上运行脚本,(Dir.entries(d) - %w[ . .. ]).empty?
可能会更好。
我已经在Mac OS X上对此进行了相当多的测试,即使使用递归空目录,它也能正常工作。
- 1. 如何删除一个目录递归
- 2. emacs递归删除目录?
- 3. 递归删除目录
- 4. 递归地删除目录
- 5. 递归删除目录
- 6. Ruby递归目录
- 7. 如何在Python中查找递归空目录?
- 8. 消除递归删除空目录算法
- 9. 递归删除树目录结构中的空项目
- 10. 查找名为“归档”和删除文件的目录
- 11. 延迟时删除目录递归
- 12. 递归删除目录用C
- 13. 如何递归删除空对象?
- 14. 在C++中通过递归查找目录和子目录
- 15. Ruby删除目录
- 16. CMD:我如何递归删除“隐藏” - 文件和目录的属性
- 17. 如何查找和删除空文件?
- 18. 以递归方式查找空文件夹并递归删除它们
- 19. PHP使用SPL迭代器递归删除空目录
- 20. 如何递归移除目录?
- 21. 查找并删除空文件夹递归没有“-empty”参数
- 22. PHP的 - 如何递归删除数组的空条目?
- 23. 如何递归删除以“xxxxx”开头的目录?
- 24. 如何使用Perl递归删除所有.svn目录?
- 25. 删除Unix中的递归目录(无限子目录)
- 26. 如何删除左递归
- 27. 如何删除递归?
- 28. 为什么我有递归删除目录的问题?
- 29. 删除目录,如果空
- 30. 在C中递归删除文件和目录#
首先想到的是:系统“find。-type d | xargs rmdir -p 2>/dev/null” – kch 2009-08-17 21:53:27
只需要注意,我不想在命令行中一次性执行此操作。它将成为一个红宝石脚本。你上面的是一个cmd行版本no? – 2009-08-17 21:55:07
好吧,这是一个shell命令,是的,但是使用'Kernel.system'从ruby中调用;) – kch 2009-08-17 22:02:25