Obtener una lista de carpetas en un directorio


90

¿Cómo obtengo una lista de las carpetas que existen en un directorio determinado con ruby?

Dir.entries() parece cercano pero no sé cómo limitarlo solo a carpetas.

Respuestas:


71

Jordan está cerca, pero Dir.entriesno devuelve el camino completo que File.directory?esperaba. Prueba esto:

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

3
Tenga en cuenta que esto le permitirá obtener todos los directorios, incluidos los ocultos, así como '.'(directorio actual) y '..'(padre del directorio actual). En la mayoría de los casos, desea eliminar al menos esos dos.
Telemachus

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

Pero encontré una solución mucho más clara y concisa, usando Dir.glob.
Victor

Esto es objetivamente peor que Dir.glob()como se ve en la otra respuesta; recomiendo encarecidamente hacer eso en lugar de esto
Dasmowenator

106

Encontré esto más útil y fácil de usar:

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

obtiene todas las carpetas del directorio actual, excluidas .y ...

Para carpetas recurrentes, simplemente use **en lugar de *.

La Dir.globlínea también se puede pasar Dir.chdircomo un bloque:

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

17
Para carpetas recurrentes, debe usar **/*en lugar de *.
mkmurray

1
Simple y mejor. Gracias
Biswajit Das

Excelente respuesta.
Retroriff

47

En mi opinión, Pathnamees mucho más adecuado para nombres de archivo que cadenas simples.

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

Esto le da una matriz de todos los directorios en ese directorio como objetos Pathname.

Si quieres tener cuerdas

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

Si directory_namefuera absoluto, estas cadenas también lo son.


otra razón para usar Pathnamees que elimina de forma automática ., ..y los archivos como proprietery.DS_Store
rweng

3
más concisamente: Pathname.new (somepath) .children.select (&: directory?)
ablarg

19

Busque de forma recursiva todas las carpetas en un directorio determinado:

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

Versión no recursiva:

Dir.glob 'certain_directory/*/'

Nota: Dir.[]funciona como Dir.glob.


¿Cómo haría la búsqueda de archivos recursiva y no recursiva usando la misma lógica? ¿Y cómo archivos y carpetas recursivos y no recursivos?
píxel

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

4

Puede utilizar File.directory?desde elFileTest módulo para averiguar si un archivo es un directorio. La combinación de esto con Dir.entrieshace que sea agradable (ish) -liner:

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

Editar: actualizado según la corrección de ScottD.


3

Con este, puede obtener la matriz de una ruta completa a sus directorios , subdirectorios , subsubdirectorios de forma recursiva. Usé ese código para cargar ansiosamente estos archivos dentro del config/applicationarchivo.

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

Además, no necesitamos lidiar con lo aburrido .y ..más. La respuesta aceptada necesitaba lidiar con ellos.



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

Para una solución genérica que probablemente desee utilizar

Dir.glob(File.expand_path(path))

Esto funcionará con rutas como ~/*/(todas las carpetas dentro de su directorio personal).


¡Gracias! Esto es muy útil.
Retroriff

1

Podemos combinar la respuesta de Borh y respuesta de Johannes a conseguir absolutamente una solución elegante para obtener los nombres de directorio en una carpeta.

# 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 las carpetas ('.' Y '..' están excluidas):

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

Carpetas y archivos:

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


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.