Obtenir une liste de dossiers dans un répertoire


90

Comment obtenir une liste des dossiers qui existent dans un certain répertoire avec ruby?

Dir.entries() semble proche mais je ne sais pas comment limiter uniquement les dossiers.

Réponses:


71

Jordan est proche, mais Dir.entriesne retourne pas le chemin complet File.directory?attendu. Essaye ça:

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

3
Notez que cela vous permettra d'obtenir tous les répertoires, y compris les répertoires cachés ainsi que '.'(répertoire courant) et '..'(parent du répertoire courant). Dans la plupart des cas, vous souhaitez supprimer au moins ces deux.
Télémaque

Je préfère celui-ci ... Dir.entries(root).select { |entry| File.directory? File.join(root, entry) and not entry.in? %w[. ..]}
Victor

Mais j'ai résumé une solution beaucoup plus claire et succincte, en utilisant le Dir.glob.
Victor

C'est juste objectivement pire que ce Dir.glob()que l'on voit dans l'autre réponse - je recommande fortement de le faire au lieu de cela
Dasmowenator

106

J'ai trouvé cela plus utile et plus facile à utiliser:

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

il obtient tous les dossiers du répertoire courant, exclus .et ...

Pour récurer les dossiers, utilisez simplement **à la place de *.

La Dir.globligne peut également être passée Dir.chdirsous forme de bloc:

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

17
Pour récurer les dossiers, vous devez utiliser **/*à la place de *.
mkmurray

1
Simple et meilleur. Merci
Biswajit Das

Excellente réponse.
retroriff

47

À mon avis, il Pathnameest beaucoup mieux adapté aux noms de fichiers que les chaînes simples.

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

Cela vous donne un tableau de tous les répertoires de ce répertoire en tant qu'objets Pathname.

Si vous voulez avoir des chaînes

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

Si directory_namec'était absolu, ces chaînes sont également absolues.


une autre raison d'utiliser Pathnameest qu'il supprime automatiquement ., ..et les fichiers propriétaires comme.DS_Store
rweng

3
plus laconique: Pathname.new (somepath) .children.select (&: directory?)
ablarg

19

Trouvez récursivement tous les dossiers dans un certain répertoire:

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

Version non récursive:

Dir.glob 'certain_directory/*/'

Remarque: Dir.[]fonctionne comme Dir.glob.


Comment feriez-vous la recherche de fichiers récursifs et non récursifs en utilisant la même logique? Et comment les fichiers et dossiers récursifs et non récursifs?
pixel

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

4

Vous pouvez utiliser à File.directory?partir du FileTestmodule pour savoir si un fichier est un répertoire. Combiner cela avec Dir.entriesfait une belle doublure (ish):

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

Edit: mis à jour par la correction de ScottD.


3

Avec celui - ci, vous pouvez obtenir le tableau d'un chemin d' accès complet à vos répertoires , sous - répertoires , subsubdirectories de manière récursive. J'ai utilisé ce code pour charger ces fichiers avec impatience dans le config/applicationfichier.

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

En outre , nous ne avons pas besoin traitons le ennuyeux .et ..plus. La réponse acceptée était nécessaire pour y faire face.



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

Pour une solution générique que vous souhaitez probablement utiliser

Dir.glob(File.expand_path(path))

Cela fonctionnera avec des chemins comme ~/*/(tous les dossiers de votre répertoire personnel).


Merci! C'est très utile.
retroriff

1

Nous pouvons combiner la réponse de Borh et la réponse de johannes pour obtenir tout à fait une solution élégante pour obtenir les noms de répertoire dans un dossier.

# 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

Seuls les dossiers («.» Et «..» sont exclus):

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

Dossiers et fichiers:

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


0

Je pense que vous pouvez tester chaque fichier pour voir s'il s'agit d'un répertoire avec FileTest.directory? (file_name). Consultez la documentation de FileTest pour plus d'informations.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.