Mendapatkan daftar folder dalam sebuah direktori


90

Bagaimana cara mendapatkan daftar folder yang ada di direktori tertentu dengan ruby?

Dir.entries() terlihat dekat tetapi saya tidak tahu cara membatasi ke folder saja.

Jawaban:


71

Jordan sudah dekat, tetapi Dir.entriestidak kembali ke jalur penuh yang File.directory?diharapkan. Coba ini:

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

3
Perhatikan bahwa ini akan memberi Anda semua direktori, termasuk yang tersembunyi serta '.'(direktori saat ini) dan '..'(induk direktori saat ini). Dalam kebanyakan kasus, Anda ingin menghapus setidaknya keduanya.
Telemakus

Saya lebih suka yang ini ... Dir.entries(root).select { |entry| File.directory? File.join(root, entry) and not entry.in? %w[. ..]}
Victor

Tapi saya menyimpulkan solusi yang jauh lebih jelas dan ringkas, menggunakan Dir.glob.
Victor

Ini secara obyektif lebih buruk daripada yang Dir.glob()terlihat pada jawaban lain - Saya sangat menyarankan untuk melakukan itu saja daripada ini
Dasmowenator

105

Menurut saya ini lebih berguna dan mudah digunakan:

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

itu mendapat semua folder di direktori saat ini, dikecualikan .dan.. .

Untuk mengulang folder, cukup gunakan **sebagai pengganti* .

The Dir.globgaris juga dapat dikirimkan ke Dir.chdirsebagai blok:

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

17
Untuk mengulang folder, Anda perlu menggunakan **/*sebagai pengganti *.
mkmurray

1
Sederhana dan terbaik. Terima kasih
Biswajit Das

1
Jawaban yang sangat bagus.
retroriff

47

Menurut pendapat saya Pathnamejauh lebih cocok untuk nama file daripada string biasa.

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

Ini memberi Anda larik semua direktori di direktori itu sebagai objek Pathname.

Jika Anda ingin memiliki string

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

Jika directory_namemutlak, string ini juga mutlak.


alasan lain untuk menggunakan Pathnameadalah bahwa secara otomatis menghapus ., ..dan file kepemilikan seperti.DS_Store
rweng

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

19

Temukan semua folder di bawah direktori tertentu secara rekursif:

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

Versi non-rekursif:

Dir.glob 'certain_directory/*/'

Catatan: Dir.[]berfungsi seperti Dir.glob.


Bagaimana Anda melakukan pencarian file rekursif dan non-rekursif menggunakan logika yang sama? Dan bagaimana file dan folder rekursif dan non-rekursif?
piksel

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

4

Anda dapat menggunakan File.directory?dari FileTestmodul untuk mengetahui apakah file adalah direktori. Menggabungkan ini dengan Dir.entriesmake untuk yang bagus (ish) -liner:

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

Edit: Diperbarui per koreksi ScottD.


3

Dengan yang satu ini, Anda bisa mendapatkan array dari path lengkap untuk Anda direktori , subdirektori , subsubdirectories dengan cara rekursif. Saya menggunakan kode itu untuk memuat file-file ini di dalam config/applicationfile.

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

Selain itu kita tidak perlu berurusan dengan yang membosankan .dan ..lagi. Jawaban yang diterima perlu berurusan dengan mereka.



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

Untuk solusi umum yang mungkin ingin Anda gunakan

Dir.glob(File.expand_path(path))

Ini akan bekerja dengan jalur seperti ~/*/(semua folder dalam direktori home Anda).


Terima kasih! Ini sangat membantu.
retroriff

1

Kita dapat menggabungkan jawaban Borh dan jawaban johannes untuk mendapatkan solusi yang cukup elegan untuk mendapatkan nama direktori dalam sebuah folder.

# 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

Hanya folder ('.' Dan '..' yang dikecualikan):

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

Folder dan file:

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


0

Saya rasa Anda dapat menguji setiap file untuk melihat apakah itu adalah direktori dengan FileTest.directory? (file_name). Lihat dokumentasi FileTest untuk info lebih lanjut.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.