2013-03-29 151 views
4

我一直試圖在Ruby中使用簡單的遞歸方法實現一個更大程序的部分目錄遍歷。但是我發現Dir.foreach不包括它裏面的目錄。我怎樣才能讓他們上市?Ruby中的目錄遍歷

代碼:

​​
+0

代替'Dir.foreach',你可以使用'Dir.glob(start)'或者'Dir [start]'。 –

+0

你想跳過'.'和'..'嗎?並且想要在'walk(start)'的每個調用中的'start'中遍歷其他人? –

+0

@iAmRubuuu是的,以避免無限遞歸。 – squiguy

回答

11

的問題是,每次遞歸的時候,你傳遞給File.directory?的路徑是不只是實體(文件或目錄)的名稱;所有上下文都會丟失。因此,假設你進入one/two/three/來檢查one/two/three/file.txt是否是一個目錄,File.directory?只是從頂層目錄的角度將"file.txt"作爲路徑而不是整個事物。每次你遞歸時你都必須保持相對路徑。這似乎很好地工作:

def walk(start) 
    Dir.foreach(start) do |x| 
    path = File.join(start, x) 
    if x == "." or x == ".." 
     next 
    elsif File.directory?(path) 
     puts path + "/" # remove this line if you want; just prints directories 
     walk(path) 
    else 
     puts x 
    end 
    end 
end 
+1

是的,它根本不打印任何東西。我一直在玩它一段時間。 – squiguy

+0

@squiguy奇怪,我只是自己試了一下,它確實有效。 –

+0

它是否在每個目錄內?我覺得我做錯了什麼。我不懷疑你! – squiguy

10

遞歸你應該使用Find

從文檔:

的查找模塊支持一組文件路徑的自頂向下穿越。

例如,以總價所有文件的大小,你的主目錄下,在一個「點」目錄忽略任何東西(如$ HOME /的.ssh):

 
require 'find' 

total_size = 0 

Find.find(ENV["HOME"]) do |path| 
    if FileTest.directory?(path) 
    if File.basename(path)[0] == . 
     Find.prune  # Don't look any further into this directory. 
    else 
     next 
    end 
    else 
    total_size += FileTest.size(path) 
    end 
end 
+1

很好找。我從來不知道這件事。 – squiguy

1

嘗試以下:

​​
+0

這不會遞歸地遍歷目錄。目錄檢查需要路徑,並且該路徑應該在遞歸調用中傳遞,以便後續的Dir.entries調用工作。 x = File.join(start,x)應該遵循Dir.entries .... –