2009-12-14 51 views

Trả lời

60

Jordan đóng, nhưng Dir.entries không trả lại đường dẫn đầy đủ mà File.directory? mong đợi. Hãy thử điều này:

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

Lưu ý rằng điều này sẽ giúp bạn có được * tất cả * thư mục, bao gồm cả thư mục ẩn cũng như ''.'' (thư mục hiện tại) và'' .. ''(thư mục gốc của thư mục hiện tại). Trong hầu hết các trường hợp, bạn muốn xóa ít nhất hai trường hợp đó. – Telemachus

+0

Điểm tốt. Đã sửa cho. và .. – scottd

0

Tôi nghĩ bạn có thể kiểm tra từng tệp để xem đó có phải là thư mục có số FileTest.directory? (file_name) hay không. Xem the documentation for FileTest để biết thêm thông tin.

4

Bạn có thể sử dụng File.directory? từ mô-đun FileTest để tìm hiểu xem tệp có phải là một thư mục hay không. Kết hợp điều này với Dir.entries làm cho một một (ish) -liner đẹp:

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

Edit: cập nhật mỗi chỉnh ScottD của.

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

Theo tôi Pathname là tốt hơn phù hợp cho tên tập tin hơn dây đồng bằng.

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

Điều này cung cấp cho bạn một loạt các thư mục trong thư mục đó làm đối tượng Đường dẫn.

Nếu bạn muốn có chuỗi

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

Nếu directory_name là tuyệt đối, những chuỗi là tuyệt đối quá.

+0

lý do khác để sử dụng 'Pathname' là nó tự động xóa' .', '..' và các tệp sở hữu như' .DS_Store' – rweng

+3

nhiều hơn: Pathname.new (somepath) .children.select (&: directory ?) – ablarg

87

Tôi đã thấy điều này hữu ích hơn và dễ sử dụng:

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

nó được tất cả các thư mục trong thư mục hiện hành, loại trừ ....

Để recurse thư mục, chỉ cần sử dụng ** thay cho *.

Dòng Dir.glob cũng có thể được truyền cho Dir.chdir như một khối:

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

Để recurse thư mục, bạn cần sử dụng '**/*' thay cho '*'. – mkmurray

+1

Đơn giản và tốt nhất. Cảm ơn bạn –

18

đệ quy tìm thấy tất cả các thư mục dưới một thư mục nhất định: phiên bản

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

Non-đệ quy:

Dir.glob 'certain_directory/*/' 

Lưu ý: Dir.[] hoạt động như Dir.glob.

+0

Làm thế nào bạn sẽ làm đệ quy và không đệ quy tập tin tìm thấy bằng cách sử dụng cùng một logic? Và cách đệ quy và không đệ quy tập tin và thư mục? – pixel

1
Dir.glob('/your_dir').reject {|e| !File.directory?(e)} 
+1

Hoặc, thay vì 'từ chối!', 'Chọn' –

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 
0

Đối với một giải pháp chung có thể bạn muốn sử dụng

Dir.glob(File.expand_path(path)) 

này sẽ làm việc với những con đường như ~/*/ (tất cả các thư mục bên trong thư mục chính của bạn).

0

Chúng tôi có thể kết hợp Borh's answerjohannes' answer để nhận được giải pháp khá thanh lịch để nhận tên thư mục trong một thư mục.

# 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 } 
0

Chỉ các thư mục ('' và '..' tự túc):

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

Folders và các tập tin:

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

Các vấn đề liên quan