Ottenere un elenco di cartelle in una directory


90

Come ottengo un elenco delle cartelle che esistono in una determinata directory con ruby?

Dir.entries() sembra vicino ma non so come limitare solo alle cartelle.

Risposte:


71

Jordan è vicino, ma Dir.entriesnon restituisce il percorso completo che si File.directory?aspetta. Prova questo:

 Dir.entries('/your_dir').select {|entry| File.directory? File.join('/your_dir',entry) and !(entry =='.' || entry == '..') }

3
Nota che questo ti porterà tutte le directory, comprese quelle nascoste così come '.'(directory corrente) e '..'(genitore della directory corrente). Nella maggior parte dei casi, vuoi rimuovere almeno quei due.
Telemaco

Preferisco questo ... Dir.entries(root).select { |entry| File.directory? File.join(root, entry) and not entry.in? %w[. ..]}
Victor

Ma ho riassunto una soluzione molto più chiara e succinta, utilizzando il Dir.glob.
Victor

Questo è solo oggettivamente peggio di Dir.glob()come visto nell'altra risposta - Consiglio vivamente di farlo invece di questo
Dasmowenator

106

L'ho trovato più utile e facile da usare:

Dir.chdir('/destination_directory')
Dir.glob('*').select {|f| File.directory? f}

ottiene tutte le cartelle nella directory corrente, escluse .e ...

Per ricorrere **alle cartelle è sufficiente utilizzare al posto di *.

La Dir.globlinea può anche essere passata Dir.chdircome blocco:

Dir.chdir('/destination directory') do
  Dir.glob('*').select { |f| File.directory? f }
end

17
Per ricorrere alle cartelle, è necessario utilizzare **/*al posto di *.
mkmurray

1
Semplice e migliore. Grazie
Biswajit Das

Ottima risposta.
retroriff

47

A mio parere Pathnameè molto più adatto per i nomi dei file rispetto alle semplici stringhe.

require "pathname"
Pathname.new(directory_name).children.select { |c| c.directory? }

Questo ti dà un array di tutte le directory in quella directory come oggetti Pathname.

Se vuoi avere delle stringhe

Pathname.new(directory_name).children.select { |c| c.directory? }.collect { |p| p.to_s }

Se directory_nameera assoluto, anche queste stringhe sono assolute.


un altro motivo per usare Pathnameè che rimuove automaticamente ., ..e file proprietery come.DS_Store
rweng

3
più conciso: Pathname.new (somepath) .children.select (&: directory?)
ablarg

19

Trova ricorsivamente tutte le cartelle in una determinata directory:

Dir.glob 'certain_directory/**/*/'

Versione non ricorsiva:

Dir.glob 'certain_directory/*/'

Nota: Dir.[]funziona come Dir.glob.


Come faresti a trovare file ricorsivi e non ricorsivi usando la stessa logica? E come file e cartelle ricorsivi e non ricorsivi?
pixel

4
directory = 'Folder'
puts Dir.entries(directory).select { |file| File.directory? File.join(directory, file)}

4

È possibile utilizzare File.directory?dal FileTestmodulo per scoprire se un file è una directory. La combinazione di questo con Dir.entriesrende un bel (ish) -liner:

directory = 'some_dir'
Dir.entries(directory).select { |file| File.directory?(File.join(directory, file)) }

Modifica: aggiornato in base alla correzione di ScottD.


3

Con questo, è possibile ottenere la matrice di un percorso completo per le vostre directory , sottodirectory , subsubdirectories in modo ricorsivo. Ho usato quel codice per caricare ansiosamente questi file all'interno del config/applicationfile.

Dir.glob("path/to/your/dir/**/*").select { |entry| File.directory? entry }

Inoltre non abbiamo bisogno di affrontare il noioso .e ..più. La risposta accettata era necessaria per affrontarli.



1
$dir_target = "/Users/david/Movies/Camtasia 2/AzureMobileServices.cmproj/media"

Dir.glob("#{$dir_target}/**/*").each do |f| 
  if File.directory?(f)
    puts "#{f}\n"
  end
end

1

Per una soluzione generica che probabilmente vorrai usare

Dir.glob(File.expand_path(path))

Funzionerà con percorsi come ~/*/(tutte le cartelle all'interno della directory home).


Grazie! Questo è molto utile.
retroriff

1

Siamo in grado di combinare la risposta di borh e risposta di Johannes per ottenere una soluzione elegante abbastanza per ottenere i nomi delle directory in una cartella.

# user globbing to get a list of directories for a path
base_dir_path = ''
directory_paths = Dir.glob(File.join(base_dir_path, '*', ''))

# or recursive version:
directory_paths = Dir.glob(File.join(base_dir_path, '**', '*', ''))

# cast to Pathname
directories = directory_paths.collect {|path| Pathname.new(path) }

# return the basename of the directories
directory_names = directories.collect {|dir| dir.basename.to_s }

1

Solo le cartelle ("." E ".." sono escluse):

Dir.glob(File.join(path, "*", File::SEPARATOR))

Cartelle e file:

Dir.glob(File.join(path, "*"))


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.