2011-07-21 7 views
29

używając ruby, jak uzyskać liczbę plików w danym katalogu, liczba plików powinna zawierać liczbę z katalogów rekursywnych.jak uzyskać liczbę plików w katalogu używając ruby ​​

Np .: folder1 (2 pliki) -----> folder2 (4 pliki) i folder2 znajduje się w folderze1. Łączna liczba dla powyższego przypadku powinna wynosić 6 plików.

czy jest jakaś funkcja w rubinach, która przyniosła mi tę liczbę.

Odpowiedz

31

Najszybciej powinno być (nie wliczając w katalogach liczą):

Dir.glob(File.join(your_directory_as_variable_or_string, '**', '*')).select { |file| File.file?(file) }.count 

i krótsze:

dir = '~/Documents' 
Dir[File.join(dir, '**', '*')].count { |file| File.file?(file) } 
+0

jej ładny kod jedna wkładka, dzięki człowiek –

+0

no problemo! :) –

+0

Czy możesz wyjaśnić, dlaczego pierwsza metoda powinna być szybsza od drugiej? A może źle zrozumiałem, co rozumiesz przez "najszybszą drogę". – Automatico

23

Wszystko czego potrzebujesz to ten, prowadzony w bieżącym katalogu.

Dir["**/*"].length 

Zlicza katalogi jako pliki.

0

Spróbuj:

//we suppose that the variable folder1 is an absolute path here 
pattern = File.join(folder1, "**", "*") 
count = Dir.glob(pattern).count 
6

niewielkimi zmianami i komentarz

Dir['**/*'].count { |file| File.file?(file) } 

działa na mnie w Ruby 1.9.3, oraz jest krótsza.

Ograniczeniem, przynajmniej na moim komputerze z Windows 7, jest to, że Dir['somedir/**/*'] nie działa. Muszę używać

cd(somedir) { Dir['**/*'] } 
3

Można także udać się bardzo szkielety i zrobić komendę systemową:

count = `ls -1 #{dir} | wc -l`.to_i 
1

jak o następujące elementy:

find . -typef|wc -l

Również jakie są wady korzystania z tej metody ponad Dir.count?

+1

To polecenie nie jest przenośne, ponieważ może nie działać w systemie Windows i na innej platformie, które nie zapewniają jednego z wyżej wymienionych poleceń. – xhochy

+2

Właściwie większość odpowiedzi nie działa w systemie Windows, ponieważ używają ukośnika '/' –

0

Najszybszym sposobem w systemie Windows na bardzo duże foldery byłoby skorzystanie z command line version of search everything w ten sposób, nie wiem, czy Linus ma coś w rodzaju Search Everything. Jeśli tak, proszę daj nam znać.

ES = 'C:\Users\...\everything\es\es.exe' 

def filelist path 
    command = %Q{"#{ES}" "#{path}\\*"} 
    list = [] 
    IO.popen(command+" 2>&1") do |pipe| 
    while lijn = pipe.gets 
     list << lijn 
    end 
    end 
    list 
end 

filelist(path).count 

zobaczyć tutaj wyniki dla stosunkowo niewielkiej folderu (+800 plików)

Benchmark.bmbm do |x| 
    x.report("glob  ") { filelist(path).count } 
    x.report("everything") { Dir.glob("#{folder}/**/*").count } 
end 

Rehearsal ---------------------------------------------- 
glob   0.000000 0.032000 0.032000 ( 0.106887) 
everything 0.000000 0.000000 0.000000 ( 0.001979) 
------------------------------------- total: 0.032000sec 

       user  system  total  real 
glob   0.016000 0.015000 0.031000 ( 0.110030) 
everything 0.000000 0.016000 0.016000 ( 0.001881)