Abrufen einer Liste von Ordnern in einem Verzeichnis


89

Wie erhalte ich eine Liste der Ordner, die in einem bestimmten Verzeichnis mit Ruby vorhanden sind?

Dir.entries() sieht genau aus, aber ich weiß nicht, wie ich mich nur auf Ordner beschränken soll.

Antworten:


71

Jordan ist nah dran, gibt aber Dir.entriesnicht den vollen Weg zurück, den man File.directory?erwartet. Versuche dies:

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

3
Beachten Sie, dass Sie dadurch alle Verzeichnisse erhalten, einschließlich der versteckten sowie '.'(aktuelles Verzeichnis) und '..'(übergeordnetes Verzeichnis des aktuellen Verzeichnisses). In den meisten Fällen möchten Sie mindestens diese beiden entfernen.
Telemachos

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

Aber ich habe eine Lösung gefunden, die viel klarer und prägnanter ist, indem ich die Dir.glob.
Victor

Dies ist nur objektiv schlimmer als Dir.glob()in der anderen Antwort zu sehen - ich würde dringend empfehlen, dies stattdessen zu tun
Dasmowenator

106

Ich fand das nützlicher und benutzerfreundlicher:

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

Es werden alle Ordner im aktuellen Verzeichnis abgerufen, ausgeschlossen .und ...

Um Ordner zu rekursieren, verwenden Sie einfach **anstelle von *.

Die Dir.globZeile kann auch Dir.chdirals Block übergeben werden:

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

17
Um Ordner zu rekursieren, müssen Sie **/*anstelle von verwenden *.
mkmurray

1
Einfach und am besten. Vielen Dank
Biswajit Das

Hervorragende Antwort.
Retroriff

47

Meiner Meinung nach Pathnameist es für Dateinamen viel besser geeignet als für einfache Zeichenfolgen.

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

Dadurch erhalten Sie ein Array aller Verzeichnisse in diesem Verzeichnis als Pfadnamenobjekte.

Wenn Sie Zeichenfolgen haben möchten

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

Wenn directory_nameabsolut, sind diese Zeichenfolgen auch absolut.


ein weiterer Grund für die Verwendung Pathnameist , dass es automatisch entfernt ., ..und proprietery Dateien wie.DS_Store
rweng

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

19

Suchen Sie rekursiv alle Ordner in einem bestimmten Verzeichnis:

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

Nicht rekursive Version:

Dir.glob 'certain_directory/*/'

Hinweis: Dir.[]funktioniert wie Dir.glob.


Wie würden Sie rekursive und nicht rekursive Dateisuche mit derselben Logik durchführen? Und wie rekursiv und nicht rekursiv Dateien und Ordner?
Pixel

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

4

Sie können anhand File.directory?des FileTestModuls herausfinden, ob eine Datei ein Verzeichnis ist. Die Kombination mit Dir.entriesergibt einen schönen (ish) -Liner:

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

Bearbeiten: Aktualisiert gemäß ScottD-Korrektur.


3

Mit diesem können Sie das Array eines vollständigen Pfads zu Ihren Verzeichnissen , Unterverzeichnissen und Unterverzeichnissen auf rekursive Weise abrufen . Ich habe diesen Code verwendet, um diese Dateien eifrig in die config/applicationDatei zu laden .

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

Darüber hinaus brauchen wir nicht mit den langweiligen beschäftigen .und ..mehr. Die akzeptierte Antwort musste sich mit ihnen befassen.



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

Für eine generische Lösung möchten Sie wahrscheinlich verwenden

Dir.glob(File.expand_path(path))

Dies funktioniert mit Pfaden wie ~/*/(alle Ordner in Ihrem Home-Verzeichnis).


Vielen Dank! Das ist sehr hilfreich.
Retroriff

1

Wir können kombinieren Born Antwort und johannes' Antwort zu bekommen recht eine elegante Lösung zu bekommen , die Verzeichnisnamen in einem Ordner.

# 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

Nur Ordner ('.' Und '..' sind ausgeschlossen):

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

Ordner und Dateien:

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


0

Ich denke, Sie können jede Datei testen, um festzustellen, ob es sich um ein Verzeichnis mit handelt FileTest.directory? (file_name). Weitere Informationen finden Sie in der Dokumentation zu FileTest .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.