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.

0xC0DEFACE
la source

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 == '..') }
Scottd
la source
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
Emiliano Poggi
la source
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.

Johannes
la source
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.

Bohr
la source
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)}
Markus
la source
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.

Jordan Running
la source
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.

Victor
la source
1
Dir.glob('/your_dir').reject {|e| !File.directory?(e)}
msangui
la source
1
Ou, au lieu de reject !,select
Fund Monica's Lawsuit
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
David Douglas
la source
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).

cette conception
la source
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 }
br3nt
la source
1

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

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

Dossiers et fichiers:

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

Iwan B.
la source
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.

matekm
la source