2017-03-17 84 views
2

我寫了下面的腳本通過目錄遍歷,它的子目錄和它們的文件:紅寶石:通過DIR的和文件遍歷

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 

鑑於followiing目錄+文件結構:

- 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

你熟悉'Dir.glob(「./**/*」)',這將給你所有的目錄和文件的列表? –

+0

@maxple no ..... – jonhue

回答

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 
+0

謝謝你的回答!我完全理解你的觀點。你的兩個解決方案都工作 - 到目前爲止還不知道'pathname'。一個(意想不到的)問題,我把它添加到帖子中。 – jonhue

+1

@jonhue:'**'已經意味着「任何深度」。 「**/*」對於任何深度都足夠了。至於你的'nil',我沒有看到任何理由,它應該與你的測試字符串不同。 –

+0

嗯..當我添加'puts'到那條線時,我總是以類似':23' – jonhue