【问题标题】:How do I read a gzip file line by line?如何逐行读取 gzip 文件?
【发布时间】:2011-12-31 07:40:20
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: ruby file-io gzip


    【解决方案1】:

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

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

    【讨论】:

    • 读取完成后是否会自动关闭文件?
    • 是和否 - 如果 GzipReader 直接对文件进行操作,您可能需要关闭它。但在这种情况下,我假设open 方法会打开文件,因此您必须关闭inline IO 流。
    • 哇!! 4 年过去了,仍然在回答 cmets 的问题。现在是奉献!再次感谢。
    • @Tigraine 获取 - list_failed_logins.rb:2:未初始化的常量 Zlib (NameError)
    • @AjayAradhya 您可能需要在文件中添加require 'zlib'
    【解决方案2】:

    试试这个:

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

    【讨论】:

    • 使用while 有效,但@Tigraine 显示的each_line 在Ruby 中更为惯用。
    • 我知道。我什至想删除我的答案,但为了完整起见,我决定留下它。
    • 这是一个很好的理由。我会定期展示完成某事的替代方法。而且,这就是 Ruby 的美妙之处,我们可以用更接近于我们在其他语言中学习的方式编写代码,这有助于我们作为程序员更容易访问和移植它。这符合 Matz 对开发人员透明的目标。
    【解决方案3】:

    其他答案显示了如何逐行读取文件,而不是如何只捕获一次错误。基于@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
    

    Set 的作用类似于 Array,但使用 Hash 构建,因此它类似于 Hash,但我们只关心键,即只存储唯一值。如果您尝试添加重复项,它们将被丢弃,只留下唯一值。您可以使用 Array,然后在其上使用 uniq,但 Set 会预先为您管理它。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-19
      • 2011-11-02
      • 2011-12-22
      • 1970-01-01
      相关资源
      最近更新 更多