【问题标题】:Skipping the first line when reading in a file in 1.9.3在 1.9.3 中读取文件时跳过第一行
【发布时间】:2012-03-25 18:01:00
【问题描述】:

我正在使用 ruby​​ 的文件来打开和读取 rake 内的文本文件 任务。有没有可以指定我想要第一行的设置 文件跳过? 到目前为止,这是我的代码:

desc "Import users." 
  task :import_users => :environment do 
    File.open("users.txt", "r", '\r').each do |line| 
      id, name, age, email = line.strip.split(',') 
      u = User.new(:id => id, :name => name, :age => age, :email => email) 
      u.save 
    end 
  end

我尝试了line.lineno,也尝试了File.open("users.txt", "r", '\r').each do |line, index| 和next if index == 0,但没有任何运气。

【问题讨论】:

    标签: ruby rake-task ruby-1.9.3


    【解决方案1】:

    将each 更改为each_with_index do |line, index| 和next if index == 0 即可。

    【讨论】:

      【解决方案2】:
      File.open("users.txt", "r", '\r') do |file|
        lines = file.lines # an enumerator
        lines.next #skips first line
        lines.each do |line|
          puts line # do work
        end
      end
      

      使用枚举器,它“记住”它在哪里。

      【讨论】:

        【解决方案3】:

        您可能真的想使用 csv:

        CSV.foreach("users.txt", :headers, :header_converters => :symbol, :col_sep => ',') do |row|
          User.new(row).save
        end 
        

        【讨论】:

          【解决方案4】:
          File.readlines('users.txt')[1..-1].join()
          

          效果也不错。

          【讨论】:

          • File.readlines('users.txt').drop(1).join 更简单一点:)
          【解决方案5】:

          函数drop(n) 将从开头删除n 行:

          File.readlines('users.txt').drop(1).each do |line| 
            puts line
          end 
          

          它将整个文件读入一个数组并删除第一行n。如果您正在阅读整个文件,这可能是最优雅的解决方案。

          【讨论】:

          • 你的意思是 File.readlines("users.txt").drop(1).each do |line| ,你的例子给出了一个错误
          【解决方案6】:

          如果您想始终将文件保留为 IO(无数组转换)并且您计划使用第一行中的数据:

          f = File.open('users.txt', 'r')
          first_line = f.gets
          body = f.readlines
          

          正如其他人指出的那样,您想要的更有可能由 CSV 或 FasterCSV 处理。我最喜欢处理带有标题行的文件的方法是:

          FasterCSV.table('users.txt')
          

          【讨论】:

            【解决方案7】:

            由于一些答案(不再是?)在 Ruby 1.9.3 中有效,这里是三种最佳方法的工作示例

            # this line must be dropped
            puts "using drop"
            File.readlines(__FILE__).drop(1).each do |line| 
              puts line
            end 
            puts ""
            
            puts "using a range"
            File.readlines(__FILE__)[1..-1].each do |line| 
              puts line
            end
            puts ""
            
            puts "using enumerator"
            File.readlines(__FILE__).each do |file, w|
                lines = file.lines # an enumerator
                lines.next #skips first line
                lines.each do |line|
                    puts line
                end
            end
            

            【讨论】:

              【解决方案8】:

              OP 说lineno 对他们不起作用,但我猜它没有以正确的方式应用。有很多方法可以实现 OP 的要求,但使用 lineno 可能会帮助您缩短代码,而不必使用 readlines,这有时会占用大量内存。

              来自1.9.3 docs

              f = File.new("testfile")
              f.each {|line| puts "#{f.lineno}: #{line}" }
              

              产生:

              1: This is line one
              2: This is line two
              3: This is line three
              4: And so on...
              

              请注意,这是您可以从文件对象调用的方法,但不能从块中生成的对象调用。

                 2:     require 'pry'; binding.pry
              => 3:   f.each {|line| puts line.lineno }
              
              [1] pry(#<SomeFile>)> line.lineno
              NoMethodError: undefined method `lineno' for #<String:0x00007fa7d682b920>
              

              您可以在 Ruby 最新稳定版本 (2.5.1) 的文档中找到相同的 example 和相同的代码。

              所以离开这个例子,代码可能看起来像

              f = File.new("testfile")
              o = File.open("output.txt", w)
              f.each do |line|
                next if f.lineno == 1
                o << line
              end
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2014-01-26
                • 2013-03-25
                • 1970-01-01
                • 1970-01-01
                • 2016-03-28
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多