Ruby:迭代dir和文件

时间:2017-03-17 21:12:54

标签: ruby-on-rails ruby file loops directory

我编写了以下脚本来遍历目录,它的子目录及其文件:

    def self.search_files_in_dir_for(dir, strings)
        results = {}
        puts "Initializing test ..."
        Dir.foreach(dir) do |file|
            next if file == '.' or file == '..'
            puts 'TEST: Testing dir "' + dir + "/" + file + '"'
            if File.file?(file)
                puts 'TEST: Testing "' + dir + "/" + file + '"'
                line_number = 0
                IO.foreach(file) do |line|
                    line_number = line_number + 1
                    if strings.any? { |string| line.include?(string) }
                        string = strings.detect { |string| line.include?(string) }
                        puts source = file + ":" + line_number.to_s
                        results[source] = string
                    end
                end
            elsif File.directory?(file)
                # Search child directories
                search_files_in_dir_for(File.join(dir, file), strings)
            end
        end
    end

鉴于后续的dir +文件结构:

- views
  - application
    - abcdefg
      - _partial2.html.erb
    - _partial1.html.erb
  - layouts
    - application.html.erb

当将views目录的路径作为dir传递时,我得到了输出:

Initializing test ...
TEST: Testing dir "views/application"
TEST: Testing dir "views/layouts"

我希望这样的事情:

Initializing test ...
TEST: Testing dir "views/application"
TEST: Testing dir "views/application/abcdefg"
TEST: Testing "views/application/abcdefg/_partial2.html.erb"
TEST: Testing "views/application/_partial1.html.erb"
TEST: Testing dir "views/layouts"
TEST: Testing "views/layouts/application.html.erb"

我在那个剧本中做错了什么?

1 个答案:

答案 0 :(得分:2)

路径名#水珠

明显较短的版本,使用PathnamePathname.glob

require 'pathname'
files, dirs = Pathname.glob('**/*').partition(&:file?)

它为您提供了两个数组:一个包含当前目录中的所有文件,另一个包含所有子文件夹。

对于特定的dir

files, dirs = Pathname.glob(File.join(dir, '**/*')).partition(&:file?)

您只需要解析files

的内容

Grep或ack?

您似乎正在尝试复制grepackgit grep

您的代码,已修复

这是您的代码的修改版本。最大的问题是file是一个相对路径。 File.file?(file)始终返回false

@results = {}
def search_files_in_dir_for(dir, strings)
  Dir.foreach(dir) do |file|
    complete_path = File.join(dir, file)
    next if file == '.' or file == '..'
    if File.file?(complete_path)
      puts "TEST: Testing '#{complete_path}'"
      line_number = 0
      IO.foreach(complete_path) do |line|
        line_number = line_number + 1
        if strings.any? { |string| line.include?(string) }
          string = strings.detect { |string| line.include?(string) }
          source = complete_path + ":" + line_number.to_s
          @results[source] = string
        end
      end
    else
      # Search child directories
      search_files_in_dir_for(complete_path, strings)
    end
  end
end

search_files_in_dir_for(..., [..., ...])

p @results