Как мне прочитать файл gzip построчно? - PullRequest
10 голосов
/ 31 декабря 2011

У меня есть файл gzip, и в настоящее время я читаю его так:

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

Я думаю, что это преобразует файл в строку, но я хотел бы прочитать его построчно.

Что я хочу сделать, так это чтобы в файле было несколько предупреждающих сообщений с мусором, я хочу создать эти предупреждающие сообщения и записать их в другой файл.Но некоторые предупреждающие сообщения повторяются, поэтому я должен убедиться, что я только grep их один раз.Следовательно, построчное чтение помогло бы мне.

Ответы [ 3 ]

20 голосов
/ 31 декабря 2011

Вы должны иметь возможность просто зацикливать читатель gzip, как вы делаете с обычными потоками ( в соответствии с документами )

infile = open("file.log.gz")
gz = Zlib::GzipReader.new(infile)
gz.each_line do |line|
  puts line
end
1 голос
/ 31 декабря 2011

Другие ответы показывают, как читать файл построчно, а не как фиксировать ошибки только один раз.Опираясь на ответ @ 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, но нас интересуют только ключи, т.е. сохраняются только уникальные значения.Если вы попытаетесь добавить дубликаты, они будут выброшены, и у вас останутся только уникальные значения.Вы можете использовать массив, а затем использовать uniq на нем, но набор будет управлять им заранее.

>> require 'set'
=> true
>> errors = Set.new
=> #<Set: {}>
>> errors << 'a'
=> #<Set: {"a"}>
>> errors << 'b'
=> #<Set: {"a", "b"}>
>> errors << 'a'
=> #<Set: {"a", "b"}>
1 голос
/ 31 декабря 2011

Попробуйте это:

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