我有一个gzip文件,现在我是这样读取它的:
infile = open("file.log.gz")
gz = Zlib::GzipReader.new(infile)
output = gz.read
puts result
我认为这将文件转换为字符串,但我想逐行读取它。
我的目的是:文件中有一些带有垃圾信息的警告消息,我想要筛选那些警告消息并将它们写入另一个文件。但是有些警告消息是重复的,所以我必须确保只筛选一次。因此,逐行阅读会对我有所帮助。
根据文档,您应该能够像处理常规流一样循环使用gzip reader(详见文档)
infile = open("file.log.gz")
gz = Zlib::GzipReader.new(infile)
gz.each_line do |line|
puts line
end
试一试:
infile = open("file.log.gz")
gz = Zlib::GzipReader.new(infile)
while output = gz.gets
puts output
end
while
是可以的,但像 @Tigraine 展示的那样,使用 each_line
更符合 Ruby 的惯用方式。 - the Tin Manrequire '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"}>
require 'zlib'
。 - Tigraine