在1.9.3中读取文件时跳过第一行

时间:2012-03-08 08:04:11

标签: ruby rake-task ruby-1.9.3

我正在使用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,但没有运气。

8 个答案:

答案 0 :(得分:22)

each更改为each_with_index do |line, index|next if index == 0将有效。

答案 1 :(得分:16)

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

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

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

答案 2 :(得分:9)

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 :(得分:4)

您可能真的想使用csv:

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

答案 4 :(得分:4)

File.readlines('users.txt')[1..-1].join()

也很好用。

答案 5 :(得分:1)

如果你想将文件保持为IO整个时间(没有数组转换),你打算使用第一行中的数据:

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

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

FasterCSV.table('users.txt')

答案 6 :(得分:1)

由于一些答案(不再是?)在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

答案 7 :(得分:0)

OP表示100,000对他们不起作用,但是我猜想它的应用方式不正确。有很多方法可以满足OP的要求,但是使用lineno可以帮助您缩短代码,而不必使用lineno,这有时会占用大量内存。

1.9.3 docs

readlines

产生:

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.5.1),您可以在文档中找到具有相同代码的相同example

因此,从示例开始,代码可能看起来像

   2:     require 'pry'; binding.pry
=> 3:   f.each {|line| puts line.lineno }

[1] pry(#<SomeFile>)> line.lineno
NoMethodError: undefined method `lineno' for #<String:0x00007fa7d682b920>