如何逐行读取gzip文件?

时间:2011-12-30 21:08:47

标签: ruby file-io gzip gz

我有一个gzip文件,目前我读的是这样的:

infile = open("file.log.gz")
gz = Zlib::GzipReader.new(infile)
output = gz.read
puts result

我认为这会将文件转换为字符串,但我想逐行阅读。

我想要完成的是该文件有一些带有一些垃圾的警告消息,我想grep这些警告消息然后将它们写入另一个文件。但是,一些警告信息会重复出现,所以我必须确保我只对它们进行一次grep。因此,逐行阅读将有助于我。

3 个答案:

答案 0 :(得分:19)

您应该像使用常规流(according to the docs)一样简单地遍历gzip阅读器

infile = open("file.log.gz")
gz = Zlib::GzipReader.new(infile)
gz.each_line do |line|
  puts line
end

答案 1 :(得分:1)

试试这个:

infile = open("file.log.gz")
gz = Zlib::GzipReader.new(infile)
while output = gz.gets
  puts output
end

答案 2 :(得分:1)

其他答案显示了如何逐行读取文件,而不是如何仅捕获错误一次。以@Tigraine的答案为基础:

require 'set'

infile = open("file.log.gz")
gz = Zlib::GzipReader.new(infile)

errors = Set.new
# or ...
# errors = [].to_set

gz.each_line do |line|
  errors << line if (line[/^Error:/])
  # or ...
  # errors << line if (line['Error:'])
end

puts errors

设置类似于Array的行为,但是使用Hash构建,所以它就像一个哈希,但我们只关心键,即只存储唯一值。如果您尝试添加重复项,它们将被丢弃,只留下唯一值。您可以使用数组,然后在其上使用uniq,但是Set会预先为您管理它。

>> require 'set'
=> true
>> errors = Set.new
=> #<Set: {}>
>> errors << 'a'
=> #<Set: {"a"}>
>> errors << 'b'
=> #<Set: {"a", "b"}>
>> errors << 'a'
=> #<Set: {"a", "b"}>