2009-11-18 10 views

risposta

401

Hai anche la possibilità di scelta rapida del

Dir["/path/to/search/*"] 

e se si desidera trovare tutti i file Ruby in qualsiasi cartella o sottocartella:

Dir["/path/to/search/**/*.rb"] 
+5

Oppure puoi fare lo stesso con Dir :: glob() –

+1

Grazie mille, sto usando Dir [] proprio adesso. :) –

+2

Inoltre, usare './...' piuttosto che '~ /' –

129
Dir.entries(folder) 

esempio:

Dir.entries(".") 

Fonte: http://ruby-doc.org/core/classes/Dir.html#method-c-entries

+13

Sembra che sta usando SO per documentare le risposte alle domande che ha appena chiesto. Una specie di promemoria, suppongo. Non riesco a vedere molto male in questo: dopo tutto, anche se questo è un po 'incompleto (ad esempio, "Dir # glob" potrebbe essere stato citato, per esempio) non c'è nulla che impedisca a qualcun altro di postare una Risposta davvero buona. "Certo, sono per lo più un" bicchiere mezzo pieno "come un tipo ... –

+1

@ Mike: Nel grande schema delle cose, probabilmente non è un grosso problema. E come dici tu se le domande e le risposte erano buone, potrebbe essere un plus generale per il sito. Ma qui sia la domanda che la risposta sono così minime che non sembrano particolarmente utili. – Telemachus

+13

@Telemachus Uso raramente 'Dir', e ogni volta che ne ho bisogno devo leggere la documentazione. Ho postato la mia domanda e la risposta qui in modo da poterlo trovare più tardi, e forse anche aiutare qualcuno con la stessa domanda. Penso di aver sentito al podcast SO che non c'è nulla di sbagliato in un simile comportamento. Se hai una risposta migliore, per favore pubblicala. Ho pubblicato quello che so, non sono un ninja rubino. Accetto regolarmente le risposte con il maggior numero di voti. –

73

I seguenti frammenti esattamente mostra il nome dei file all'interno di una directory, sottodirectory saltare e ".", ".." cartelle tratteggiate:

Dir.entries("your/folder").select {|f| !File.directory? f} 
+16

Può anche fare '... selezionare {| f | File.file? f} 'per significato più chiaro e sintassi più breve. – Automatico

+0

Vedo che Dir.entries non restituisce il percorso completo nel nome del file restituito, quindi questa soluzione non ha funzionato per me. –

+4

@ Cort3z, non funziona per me. – squixy

27

per ottenere tutti i file (rigorosamente file solo) in modo ricorsivo:

Dir.glob('path/**/*').select{ |e| File.file? e } 
(file File.file? rifiuterebbe non regolari)

o qualsiasi cosa che non è una directory:

Dir.glob('path/**/*').reject{ |e| File.directory? e } 

soluzione alternativa

Utilizzando Find#find più di un metodo di ricerca di pattern-based come Dir.glob è effettivamente migliore. Vedi this answer to "One-liner to Recursively List Directories in Ruby?".

8

Personalmente, ho trovato questo il più utile per il ciclo su file in una cartella, lungimirante sicurezza:

Dir['/etc/path/*'].each do |file_name| 
    next if File.directory? file_name 
end 
6

Questa è una soluzione per trovare i file in una directory:

files = Dir["/work/myfolder/**/*.txt"] 

files.each do |file_name| 
    if !File.directory? file_name 
    puts file_name 
    File.open(file_name) do |file| 
     file.each_line do |line| 
     if line =~ /banco1/ 
      puts "Found: #{line}" 
     end 
     end 
    end 
    end 
end 
3

Mentre ottenendo tutti i nomi dei file in una directory, questo snippet può essere utilizzato per rifiutare entrambe le directory [., ..] e i file nascosti che iniziano con .

files = Dir.entries("your/folder").reject {|f| File.directory?(f) || f[0].include?('.')} 
+0

' Dir.entries' restituisce i nomi di file locali, non i percorsi di file assoluti. D'altra parte, 'File.directory? 'Si aspetta un percorso di file assoluto. Questo codice non funziona come previsto. – Nathan

+0

È strano che il codice non funzioni nel tuo caso. Dato che questo è un codice che ho usato in un'app live che funziona bene. Ricontrollerò il mio codice e posterò qui se manca qualcosa del mio codice di lavoro originale :) – Lahiru

+1

@Nathan Vedi la mia risposta per una spiegazione – nus

0
def get_path_content(dir) 
    queue = Queue.new 
    result = [] 
    queue << dir 
    until queue.empty? 
    current = queue.pop 
    Dir.entries(current).each { |file| 
     full_name = File.join(current, file) 
     if not (File.directory? full_name) 
     result << full_name 
     elsif file != '.' and file != '..' 
      queue << full_name 
     end 
    } 
    end 
    result 
end 

rendimenti relativi percorsi del file dalla directory e tutte le sottodirectory

7

Questo funziona per me:

Se non si desidera che i file nascosti [1], utilizzano Dir []:

# With a relative path, Dir[] will return relative paths 
# as `[ './myfile', ... ]` 
# 
Dir[ './*' ].select{ |f| File.file? f } 

# Want just the filename? 
# as: [ 'myfile', ... ] 
# 
Dir[ '../*' ].select{ |f| File.file? f }.map{ |f| File.basename f } 

# Turn them into absolute paths? 
# [ '/path/to/myfile', ... ] 
# 
Dir[ '../*' ].select{ |f| File.file? f }.map{ |f| File.absolute_path f } 

# With an absolute path, Dir[] will return absolute paths: 
# as: [ '/home/../home/test/myfile', ... ] 
# 
Dir[ '/home/../home/test/*' ].select{ |f| File.file? f } 

# Need the paths to be canonical? 
# as: [ '/home/test/myfile', ... ] 
# 
Dir[ '/home/../home/test/*' ].select{ |f| File.file? f }.map{ |f| File.expand_path f } 

Ora, Dir.entries tornerà file nascosti, e che non è necessario l'aster jolly ix (è possibile semplicemente passare la variabile con il nome della directory), ma restituirà direttamente il basename, quindi le funzioni File.xxx non funzioneranno.

# In the current working dir: 
# 
Dir.entries('.').select{ |f| File.file? f } 

# In another directory, relative or otherwise, you need to transform the path 
# so it is either absolute, or relative to the current working dir to call File.xxx functions: 
# 
home = "/home/test" 
Dir.entries(home).select{ |f| File.file? File.join(home, f) } 

[1] .dotfile su UNIX, non so su Windows

0

Se si vuole ottenere un array di nomi di file compresi i collegamenti simbolici, utilizzare

Dir.new('/path/to/dir').entries.reject { |f| File.directory? f } 

o addirittura

Dir.new('/path/to/dir').reject { |f| File.directory? f } 

e se si vuole andare senza collegamenti simbolici, utilizzare

Dir.new('/path/to/dir').select { |f| File.file? f } 

Come mostrato in altre risposte, utilizzare Dir.glob('/path/to/dir/**/*') invece di Dir.new('/path/to/dir') se si desidera ottenere tutti i file in modo ricorsivo.

+0

O semplicemente usa '*. *' –

0
Dir.new('/home/user/foldername').each { |file| puts file } 
1

Questo è ciò che funziona per me:

Dir.entries(dir).select { |f| File.file?(File.join(dir, f)) } 

Dir.entries restituisce un array di stringhe. Quindi, dobbiamo fornire un percorso completo del file a File.file?, a meno che lo dir sia uguale alla nostra attuale directory di lavoro. Ecco perché questo File.join().

0

Si consiglia inoltre di utilizzare Rake::FileList (purché si disponga di rake dipendenza):

FileList.new('lib/*') do |file| 
    p file 
end 

Secondo l'API:

filelists sono pigri. Quando viene fornito un elenco di pattern glob per i possibili file da includere nell'elenco dei file, anziché cercare le strutture del file per trovare i file, un FileList mantiene il modello per l'ultimo utilizzo di .

https://docs.ruby-lang.org/en/2.1.0/Rake/FileList.html

Problemi correlati