在Ruby中解析文件时跳过行的最快方法?

时间:2011-02-19 18:00:03

标签: ruby lines fileparsing

我试着寻找这个,但找不到多少。这似乎是之前可能会被问到的事情(很多次?),所以如果是这种情况我会道歉。

我想知道在Ruby中解析文件某些部分的最快方法是什么。例如,假设我知道我想要的特定功能的信息是在1000行文件的第500行和第600行之间。 (显然这类问题适用于大型文件,我只是为了举例而使用那些较小的数字),因为我知道它不会在上半部分,是否有一种忽略这些信息的快速方法?

目前我正在使用以下内容:

while  buffer = file_in.gets and file_in.lineno <600
  next unless file_in.lineno > 500
  if buffer.chomp!.include? some_string
    do_func_whatever
  end
end

它有效,但我不禁认为它可以更好地工作。

我对Ruby很陌生,并且有兴趣学习新的做事方式。

4 个答案:

答案 0 :(得分:11)

file.lines.drop(500).take(100) # will get you lines 501-600

通常情况下,您无法避免从开始直到您感兴趣的行读取文件,因为每行可以具有不同的长度。但是,您可以避免的一件事是将整个文件加载到一个大数组中。只需逐行阅读,计算并丢弃它们,直到找到你想要的东西。非常像你自己的例子。你可以把它变得更加Rubyish。

PS。 Tin Man的评论让我做了一些实验。虽然我没有找到任何理由为drop加载整个文件,但确实存在问题:drop 返回数组中文件的其余部分。这是一种可以避免的方法:

file.lines.select.with_index{|l,i| (501..600) === i}

PS2:Doh,上面的代码,虽然不是一个巨大的数组,但遍历整个文件,甚至是600以下的行。:(这是第三个版本:

enum = file.lines
500.times{enum.next} # skip 500
enum.take(100) # take the next 100

或者,如果您更喜欢FP:

file.lines.tap{|enum| 500.times{enum.next}}.take(100)

无论如何,这个独白的好处是你可以学习多种迭代文件的方法。 ;)

答案 1 :(得分:1)

我不知道是否有相同的方法为行执行此操作,但您可以在IO对象上使用seekoffset参数来“跳过”字节。

请参阅IO#seek,或参阅IO#open了解有关偏移量参数的信息。

答案 2 :(得分:0)

听起来像 rio 可能对此有所帮助。它为您提供了lines()方法。

答案 3 :(得分:0)

您可以使用IO#readlines,返回包含所有行的数组

IO.readlines(file_in)[500..600].each do |line| 
  #line is each line in the file (including the last \n)
  #stuff
end

f = File.new(file_in)
f.readlines[500..600].each do |line| 
  #line is each line in the file (including the last \n)
  #stuff
end