【发布时间】:2010-12-26 07:47:55
【问题描述】:
如何使用 ruby 获取某个目录中存在的文件夹列表?
Dir.entries() 看起来很接近,但我不知道如何仅限于文件夹。
【问题讨论】:
标签: ruby directory directory-listing
如何使用 ruby 获取某个目录中存在的文件夹列表?
Dir.entries() 看起来很接近,但我不知道如何仅限于文件夹。
【问题讨论】:
标签: ruby directory directory-listing
我认为您可以测试每个文件以查看它是否是带有FileTest.directory? (file_name) 的目录。请参阅the documentation for FileTest 了解更多信息。
【讨论】:
您可以使用FileTest 模块中的File.directory? 来确定文件是否为目录。将其与Dir.entries 结合起来,就可以得到一个不错的单(ish)-liner:
directory = 'some_dir'
Dir.entries(directory).select { |file| File.directory?(File.join(directory, file)) }
编辑:根据 ScottD 的更正更新。
【讨论】:
Jordan 已接近,但 Dir.entries 没有返回 File.directory? 期望的完整路径。试试这个:
Dir.entries('/your_dir').select {|entry| File.directory? File.join('/your_dir',entry) and !(entry =='.' || entry == '..') }
【讨论】:
'.'(当前目录)和'..'(当前目录的父目录)。在大多数情况下,您至少要删除这两个。
Dir.entries(root).select { |entry| File.directory? File.join(root, entry) and not entry.in? %w[. ..]}
Dir.glob 提出了一个更加清晰简洁的解决方案。
Dir.glob() 在其他答案中看到的更糟糕——我强烈建议这样做而不是这样做
directory = 'Folder'
puts Dir.entries(directory).select { |file| File.directory? File.join(directory, file)}
【讨论】:
在我看来,Pathname 比普通字符串更适合文件名。
require "pathname"
Pathname.new(directory_name).children.select { |c| c.directory? }
这为您提供了该目录中所有目录的数组作为路径名对象。
如果你想要字符串
Pathname.new(directory_name).children.select { |c| c.directory? }.collect { |p| p.to_s }
如果directory_name 是绝对的,那么这些字符串也是绝对的。
【讨论】:
Pathname的另一个原因是它会自动删除.、..和像.DS_Store这样的专有文件
我发现这更有用且易于使用:
Dir.chdir('/destination_directory')
Dir.glob('*').select {|f| File.directory? f}
它获取当前目录中的所有文件夹,不包括. 和..。
要递归文件夹,只需使用 ** 代替 *。
Dir.glob 行也可以作为一个块传递给Dir.chdir:
Dir.chdir('/destination directory') do
Dir.glob('*').select { |f| File.directory? f }
end
【讨论】:
**/* 代替*。
递归查找某个目录下的所有文件夹:
Dir.glob 'certain_directory/**/*/'
非递归版本:
Dir.glob 'certain_directory/*/'
注意:Dir.[] 的作用类似于 Dir.glob。
【讨论】:
Dir.glob('/your_dir').reject {|e| !File.directory?(e)}
【讨论】:
reject !,select
$dir_target = "/Users/david/Movies/Camtasia 2/AzureMobileServices.cmproj/media"
Dir.glob("#{$dir_target}/**/*").each do |f|
if File.directory?(f)
puts "#{f}\n"
end
end
【讨论】:
对于您可能想要使用的通用解决方案
Dir.glob(File.expand_path(path))
这将适用于~/*/(您的主目录中的所有文件夹)之类的路径。
【讨论】:
我们可以结合Borh's answer 和johannes' answer 来获得一个非常优雅的解决方案来获取文件夹中的目录名称。
# user globbing to get a list of directories for a path
base_dir_path = ''
directory_paths = Dir.glob(File.join(base_dir_path, '*', ''))
# or recursive version:
directory_paths = Dir.glob(File.join(base_dir_path, '**', '*', ''))
# cast to Pathname
directories = directory_paths.collect {|path| Pathname.new(path) }
# return the basename of the directories
directory_names = directories.collect {|dir| dir.basename.to_s }
【讨论】:
仅文件夹(不包括“.”和“..”):
Dir.glob(File.join(path, "*", File::SEPARATOR))
文件夹和文件:
Dir.glob(File.join(path, "*"))
【讨论】:
有了这个,您可以获得目录、子目录、子子目录的完整路径数组> 以递归方式。
我使用该代码将这些文件加载到 config/application 文件中。
Dir.glob("path/to/your/dir/**/*").select { |entry| File.directory? entry }
此外,我们不再需要处理无聊的. 和..。接受的答案需要处理它们。
【讨论】: