Bir dizindeki klasörlerin listesini alma


90

Ruby ile belirli bir dizinde bulunan klasörlerin bir listesini nasıl alabilirim?

Dir.entries() yakın görünüyor, ancak yalnızca klasörlerle nasıl sınırlandırılacağını bilmiyorum.

Yanıtlar:


71

Ürdün yakındır, ancak beklenen Dir.entriesyolu tam olarak geri vermez File.directory?. Bunu dene:

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

3
Bunun size gizli olanlar da dahil olmak üzere tüm dizinleri ve '.'(geçerli dizin) ve '..'(geçerli dizinin üst öğesi) de alacağını unutmayın . Çoğu durumda, en azından bu ikisini kaldırmak istersiniz.
Telemachus

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

Ama ben çok daha net ve özlü bir çözümü Dir.glob.
Victor

Bu, nesnel Dir.glob()olarak diğer cevapta görüldüğünden daha kötü - bunun yerine sadece bunu yapmanızı şiddetle tavsiye ederim
Dasmowenator

105

Bunu daha kullanışlı ve kullanımı kolay buldum:

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

geçerli dizindeki tüm klasörleri alır, hariç tutulur .ve ...

Klasörleri yinelemek için **yerine kullanın *.

Dir.globHattı da geçirilebilir Dir.chdirbir blok olarak:

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

17
Recurse klasörleri için, kullanmak zorunda **/*yerine *.
mkmurray

1
Basit ve en iyisi. Teşekkürler
Biswajit Das

1
Mükemmel cevap.
retroriff

47

Bana göre Pathnamedosya adları için düz dizelerden çok daha uygun.

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

Bu size o dizindeki tüm dizinlerin bir Dizisini Yol adı nesneleri olarak verir.

Eğer dizelere sahip olmak istiyorsan

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

Eğer directory_namemutlak idi, bu dizeleri çok mutlaktır.


kullanmak için bir başka neden Pathnameotomatik kaldırır olmasıdır ., ..benzeri ve proprietery dosyaları.DS_Store
rweng

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

19

Belirli bir dizin altındaki tüm klasörleri yinelemeli olarak bulun:

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

Yinelemeli olmayan sürüm:

Dir.glob 'certain_directory/*/'

Not: Dir.[]gibi çalışır Dir.glob.


Özyinelemeli ve özyinelemesiz dosya aynı mantığı kullanarak nasıl bulursunuz? Ve ne kadar yinelemeli ve yinelemeli olmayan dosya ve klasörler?
piksel

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

4

Bir dosyanın bir dizin olup olmadığını öğrenmek File.directory?için FileTestmodülden kullanabilirsiniz . Bunu Dir.entriesgüzel bir (ish) -liner ile birleştirmek:

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

Düzenleme: ScottD'nin düzeltmesine göre güncellendi.


3

Bu bir ile, bir dizi alabilirsiniz tam yol sizin için dizinleri , alt dizinleri , subsubdirectories bir özyinelemeli bir şekilde. Bu kodu, bu dosyaları config/applicationdosyanın içine yüklemek için kullandım .

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

Ayrıca sıkıcı .ve ..artık uğraşmamıza gerek yok. Kabul edilen cevabın onlarla başa çıkması gerekiyordu.



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

Genel bir çözüm için muhtemelen kullanmak isteyeceksiniz

Dir.glob(File.expand_path(path))

Bu, ~/*/(ana dizininizdeki tüm klasörler) gibi yollarla çalışacaktır .


Teşekkürler! Bu çok yardımcı.
retroriff

1

Biz birleştirebilirsiniz Borh yanıtını ve johannes' cevabını bir klasörde dizin adları almak için oldukça şık bir çözüm elde etmek.

# 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

Yalnızca klasörler ("." Ve ".." hariçtir):

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

Klasörler ve dosyalar:

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


0

Bir dizin olup olmadığını görmek için her dosyayı test edebileceğinizi düşünüyorum FileTest.directory? (file_name). Daha fazla bilgi için FileTest belgelerine bakın .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.