Iterate through every file in one directory

前端 未结 8 2006
忘了有多久
忘了有多久 2020-11-30 16:52

How do I write a loop in ruby so that I can execute a block of code on each file?

I\'m new to ruby, and I\'ve concluded that the way to do this is a do each loop.

相关标签:
8条回答
  • 2020-11-30 17:08

    Dir has also shorter syntax to get an array of all files from directory:

    Dir['dir/to/files/*'].each do |fname|
        # do something with fname
    end
    
    0 讨论(0)
  • 2020-11-30 17:12
    Dir.new('/my/dir').each do |name|
      ...
    end
    
    0 讨论(0)
  • 2020-11-30 17:13

    I like this one, that hasn't been mentioned above.

    require 'pathname'
    
    Pathname.new('/my/dir').children.each do |path|
        puts path
    end
    

    The benefit is that you get a Pathname object instead of a string, that you can do useful stuff with and traverse further.

    0 讨论(0)
  • 2020-11-30 17:13

    To skip . & .., you can use Dir::each_child.

    Dir.each_child('/path/to/dir') do |filename|
      puts filename
    end
    

    Dir::children returns an array of the filenames.

    0 讨论(0)
  • 2020-11-30 17:19

    As others have said, Dir::foreach is a good option here. However, note that Dir::foreach and Dir::entries will always include . and .. (the current and parent directories). You will generally not want to work on them, so you can use Dir::each_child or Dir::children (as suggested by ma11hew28) or do something like this:

    Dir.foreach('/path/to/dir') do |filename|
      next if filename == '.' or filename == '..'
      # Do work on the remaining files & directories
    end
    

    Dir::foreach and Dir::entries (as well as Dir::each_child and Dir::children) also include hidden files & directories. Often this is what you want, but if it isn't, you need to do something to skip over them.

    Alternatively, you might want to look into Dir::glob which provides simple wildcard matching:

    Dir.glob('/path/to/dir/*.rb') do |rb_filename|
      # Do work on files & directories ending in .rb
    end
    
    0 讨论(0)
  • 2020-11-30 17:20

    This is my favorite method for being easy to read:

    Dir.glob("*/*.txt") do |my_text_file|
      puts "working on: #{my_text_file}..."
    end
    

    And you can even extend this to work on all files in subdirs:

    Dir.glob("**/*.txt") do |my_text_file| # note one extra "*"
      puts "working on: #{my_text_file}..."
    end
    
    0 讨论(0)
提交回复
热议问题