获取目录中的文件夹列表


90

如何使用ruby获取某个目录中存在的文件夹列表?

Dir.entries() 看起来很近,但我不知道如何只限于文件夹。

Answers:


71

乔丹(Jordan)接近了,但Dir.entries没有返回File.directory?期望的完整路径。试试这个:

 Dir.entries('/your_dir').select {|entry| File.directory? File.join('/your_dir',entry) and !(entry =='.' || entry == '..') }

3
请注意,这将为您提供所有目录,包括隐藏目录以及'.'(当前目录)和'..'(当前目录的父目录)。在大多数情况下,您至少要删除这两个。
Telemachus

我更喜欢这个... Dir.entries(root).select { |entry| File.directory? File.join(root, entry) and not entry.in? %w[. ..]}
Victor

但是我使用提出了一个更加清晰和简洁的解决方案Dir.glob
维克多

从客观上来说,这比Dir.glob()其他答案更糟-我强烈建议您这样做,而不是这样做
Dasmowenator

106

我发现这更有用且易于使用:

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

17
要递归文件夹,您需要使用**/*代替*
mkmurray '02

1
简单而最好。谢谢
Biswajit Das

极好的答案。
Retroriff

47

我认为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的是会自动删除...并且proprietery文件如.DS_Store
rweng

3
更简洁:Pathname.new(somepath).children.select(&:directory?)
ablarg

19

递归查找特定目录下的所有文件夹:

Dir.glob 'certain_directory/**/*/'

非递归版本:

Dir.glob 'certain_directory/*/'

注意:的Dir.[]工作方式类似于Dir.glob


您将如何使用相同的逻辑来查找递归和非递归文件?以及如何递归和非递归的文件和文件夹?
像素

4
directory = 'Folder'
puts Dir.entries(directory).select { |file| File.directory? File.join(directory, file)}

4

您可以使用File.directory?FileTest模块到找出一个文件是一个目录。将其与Dir.entries一个很好的衬里结合在一起:

directory = 'some_dir'
Dir.entries(directory).select { |file| File.directory?(File.join(directory, file)) }

编辑:根据ScottD的更正进行了更新。


3

这一个,你可以得到一个数组完整路径到你的目录子目录subsubdirectories在递归的方式。我使用该代码渴望将这些文件加载​​到config/application文件中。

Dir.glob("path/to/your/dir/**/*").select { |entry| File.directory? entry }

此外,我们不需要应对枯燥...了。接受的答案需要处理它们。



1
$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

1

对于一般的解决方案,您可能要使用

Dir.glob(File.expand_path(path))

这将适用于以下路径~/*/(主目录中的所有文件夹)。


谢谢!这非常有帮助。
Retroriff

1

我们可以结合Borh的答案约翰的回答得到一个相当优雅的解决方案的文件夹中获取目录名。

# 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 }

1

仅文件夹(不包括“。”和“ ..”):

Dir.glob(File.join(path, "*", File::SEPARATOR))

文件夹和文件:

Dir.glob(File.join(path, "*"))


0

我认为您可以测试每个文件,以查看它是否是目录FileTest.directory? (file_name)。有关更多信息,请参见FileTest的文档

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.