快速解析简单的大文件

时间:2017-04-11 14:44:29

标签: ruby parsing text-files

我执行大文件的简单解析。 我试图从大文本文件中选择块并将这些块写入新的文本文件。我当前的方法工作非常缓慢,因为解析文件包含更多的300万字符串。 例如: 用于解析的文件:

1test
1111
2222
3333
4444
1test
5555
6666
2test
5555
4444
3test
0000
4test
9999
0000
5test
3333
3333

我想要新文件中的下一个数据:

arr = []

data = File.read("/path/to/file")

blocks = ['1test','2test','3test','4test','5test']
blocks.each do |block|

want = data.match(/#{block}(.*)#{block}/m)[0]
want.each_line do |line|
  arr << line
  File.open("/path/to/result/file", 'w') { |file| file.write("#{res.join}") }
end

end

很快,我尝试从源文件中选择特定的块。

我的代码:

{{1}}

我认为我的问题是我读了数据&#34;想要&#34;多次。 有没有办法在&#34;想要&#34;的一次传递中写入结果文件?数据?

1 个答案:

答案 0 :(得分:3)

<强>代码

require 'set'

def save_blocks(fname_in, fname_out, *blocks)
  sblocks = blocks.to_set
  save = false
  File.open(fname_out, 'w') do |f|
    File.foreach(fname_in) do |line|
      lc = line.chomp
      save = sblocks.include?(lc) if lc =~ /\A\d+test\z/
      f.write(line) if save
    end
  end
end

示例

让我们首先创建一个测试文件,其中str是问题中给出的示例字符串。

FNameIn  = "test.in"
FNameOut = "test.out"
File.write(FNameIn, str)
  #=> 135

我们可以检查一下。

puts File.read(FNameIn)
1test
1111
2222
...
3test
0000
4test
...
11test
1111

现在我们执行方法。

save_blocks(FNameIn, FNameOut, "1test", "3test", "5test")

我们可以确认输出文件写得正确。

puts File.read(FNameOut)
1test
1111
2222
3333
4444
1test
5555
6666
3test
0000
5test
3333
3333

我将blocks转换为一组仅仅是为了加快include?的操作。无需显式关闭任何文件,因为它们在各自的块返回时会关闭。