Отримання списку папок у каталозі


90

Як отримати список папок, які існують у певному каталозі з ruby?

Dir.entries() виглядає близько, але я не знаю, як обмежити лише папки.

Відповіді:


71

Йорданія близько, але Dir.entriesне повертає повного шляху, який File.directory?очікує. Спробуйте це:

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

3
Зверніть увагу, що це отримає всі каталоги, включаючи приховані, а також '.'(поточний каталог) та '..'(батьківський поточний каталог). У більшості випадків потрібно видалити принаймні ці два.
Телемах

Я віддаю перевагу цьому ... Dir.entries(root).select { |entry| File.directory? File.join(root, entry) and not entry.in? %w[. ..]}
Віктор

Але я підсумував рішення набагато чіткіше і коротше, використовуючи Dir.glob.
Віктор

Це просто об’єктивно гірше, ніж Dir.glob()видно з іншої відповіді - я настійно рекомендую просто робити це замість цього
Dasmowenator

106

Я знайшов це більш корисним і простим у використанні:

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

він отримує всі папки в поточному каталозі, виключені .та ...

Для повторного використання папок просто використовуйте **замість *.

Dir.globЛінія також може бути передана в Dir.chdirякості блоку:

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

17
Щоб скасувати папки, потрібно використовувати **/*замість *.
mkmurray

1
Просто і найкраще. Дякую
Biswajit Das

Відмінна відповідь.
ретрориф

47

На мій погляд Pathname, набагато краще підходить для імен файлів, ніж звичайні рядки.

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

Це надає вам масив усіх каталогів у цьому каталозі як об’єкти Pathname.

Якщо ви хочете мати рядки

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

Якщо directory_nameбуло абсолютним, ці рядки теж абсолютним.


ще одна причина для використання в Pathnameтому , що він автоматично видаляє ., ..і proprietery файли , такі як.DS_Store
rweng

3
більш стисло: Pathname.new (somepath) .children.select (&: directory?)
ablarg

19

Рекурсивно знаходити всі папки в певному каталозі:

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

Нерекурсивна версія:

Dir.glob 'certain_directory/*/'

Примітка: Dir.[]працює як Dir.glob.


Як би ви зробили рекурсивний і нерекурсивний пошук файлів, використовуючи однакову логіку? А як рекурсивні та нерекурсивні файли та папки?
піксель

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

4

Ви можете використовувати File.directory?з FileTestмодуля , щоб з'ясувати , чи є файл каталогом. Поєднання цього з Dir.entriesробить гарний (іш) лайнер:

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

Редагувати: оновлено відповідно до виправлення ScottD.


3

З цим, ви можете отримати масив на повний шлях до вашим каталогом , підкаталоги , рекурсивно рекурсивним чином. Я використовував цей код, щоб охоче завантажувати ці файли всередину config/applicationфайлу.

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

До того ж нам не потрібно мати справу з нудним .і ..більше. Прийнята відповідь, необхідна для боротьби з ними.



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

Для загального рішення, яке ви, мабуть, хочете використовувати

Dir.glob(File.expand_path(path))

Це буде працювати з такими шляхами, як ~/*/(усі папки у вашому домашньому каталозі).


Дякую! Це дуже корисно.
ретрориф

1

Ми можемо об'єднати відповідь Borh в і відповідь Йоханнеса отримати досить елегантне рішення , щоб отримати імена каталогів в папці.

# 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

Лише папки ("." Та ".." виключаються):

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

Папки та файли:

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


0

Я думаю, ви можете протестувати кожен файл, щоб перевірити, чи це каталог з FileTest.directory? (file_name). Для отримання додаткової інформації дивіться документацію до FileTest .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.