15

我正在使用 ruby​​ 的 File 来打开和读取 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但没有任何运气。

4

8 回答 8

22

更改eacheach_with_index do |line, index|并将next if index == 0工作。

于 2012-03-08T08:16:30.293 回答
20

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

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

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

于 2013-02-04T14:10:49.697 回答
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

Making use of an enumerator, which 'remembers' where it is.

于 2012-03-08T08:21:08.013 回答
4

您可能真的想使用 csv:

CSV.foreach("users.txt", :headers, :header_converters => :symbol, :col_sep => ',') do |row|
  User.new(row).save
end 
于 2012-03-08T08:49:49.447 回答
4
File.readlines('users.txt')[1..-1].join()

效果也很好。

于 2012-12-27T19:42:40.350 回答
1

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

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

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

FasterCSV.table('users.txt')
于 2013-05-01T23:16:37.250 回答
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
于 2014-10-29T16:48:45.803 回答
0

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

来自1.9.3 文档

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) 的文档中找到具有相同代码的相同示例。

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

f = File.new("testfile")
o = File.open("output.txt", w)
f.each do |line|
  next if f.lineno == 1
  o << line
end
于 2018-08-17T00:59:17.323 回答