递归列出Ruby函数列表的文件

6
我需要一个递归函数来列举文件夹中的文件:
def procdir(dirname)
  data = ''
  Dir.foreach(dirname) do |dir|
    dirpath = dirname + '/' + dir
    if File.directory?(dirpath) then
      if dir != '.' && dir != '..' then
        #puts "DIRECTORY: #{dirpath}" ; 
        procdir(dirpath)
      end
    else
      data += dirpath
    end
  end
  return data
end

但结果为null


你能告诉我文件系统是什么吗?dirname本身是否包含多个目录? - Arup Rakshit
1
可能是在Ruby中递归列出目录的一行代码?的重复问题。 - dbenhur
5个回答

21

Dir#glob方法提供的**通配符可以递归查找。

def procdir(dir)
  Dir[ File.join(dir, '**', '*') ].reject { |p| File.directory? p }
end

1
谢谢你们的回复,我明白了我的问题。dbenhur,你的代码很棒!这是我的代码,如果有人需要的话:def procdir(dir) Dir[ File.join(dir, '**', '*') ].reject { |p| File.directory? p } end file = procdir('mypath') #puts file file.each do |filename| #puts filename test = filename.scan(/SomeRegex/).flatten puts test (..) end谢谢大家。 - indi
很好,这正是我正在寻找的。 - GoldenWest

8
使用find模块:
require 'find'

pathes = []
Find.find('.') do |path|
  pathes << path unless FileTest.directory?(path)
end

puts pathes.inspect

7

虽然这是一个旧的主题,但也许有人会发现它很有用:

array_of_all_files = Dir .glob("**/*") .reject { |file_path| File.directory? file_path }

这段代码可以获取指定目录下的所有文件,并将其存储在一个数组中。使用Dir.glob方法可以匹配指定目录及其子目录下的所有文件路径,而.reject方法则可以过滤掉其中的目录路径,只保留文件路径。

3
为什么你重复了一个与我八个月前发布的答案几乎完全相同的答案?Dir::[]Dir.glob 相同。File.join('**', '*')是更便携的方式来表示 "**/*" - dbenhur
对不起,我不知道它们是相同的。而且我觉得这种写法更易读(可能是因为我用了很多次,从未接触过其他的表达方式)。 - Jikku Jose
@dbenhur:只是好奇,为什么 File.join('**', '*')"**/*" 更具可移植性。据我所知,它可以在 Linux/Windows/MacOS 上运行。 - Eric Duminil
@EricDuminil 因为有更多的操作系统。File::join 会使用 File::SEPARATOR 进行连接,而不是假设底层操作系统理解 / - dbenhur
1
@dbenhur:我同意,当与其他程序一起使用这些路径时可能会出现问题。但是File.join不会改变任何东西:即使在Windows上,File.join(“a”,“b”)也是“a/b” - Eric Duminil
显示剩余2条评论

1

看起来递归函数有几个问题:

  • else子句似乎与错误的if关联。它需要与第一个if关联。
  • 递归调用procdir的结果应添加到data中。

如果您将代码缩进得更加清晰,可能会更容易发现此类问题。以下内容包含两个修复程序:

def procdir(dirname)
  data = ''
  Dir.foreach(dirname) do |dir|
    dirpath = dirname + '/' + dir
    if File.directory?(dirpath) then
      if dir != '.' && dir != '..' then
        #puts "DIRECTORY: #{dirpath}" ; 
        data += procdir(dirpath)
      end
    else
      data += dirpath
    end
  end
  return data
end

感谢您的回复,我已经理解了我的问题。 - indi

0

如果你知道文件扩展名,你只需要使用这个:

Dir[Rails.root.join('config/locales/**/*.{rb,yml}')]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接