2011-12-30 18 views
8

Bir gzip dosyası var ve şu anda böyle okumak: Bir gzip dosya satırını nasıl okuyabilirim?

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

Bunun bir dizeye dosyayı dönüştürür düşünüyorum, ama satır satır okumak istiyorum.

Neyi başarmak istediğim, dosyada bazı çöplükler bulunan bazı uyarı mesajlarının bulunması, bu uyarı mesajlarını greplemek ve daha sonra başka bir dosyaya yazmak istiyorum. Ancak, bazı uyarı mesajları tekrarlanır, bu yüzden onları sadece bir kez grep ettiğime emin olmalıyım. Bu yüzden çizgi okuması bana yardımcı olur.

cevap

17

Sen Diğer cevaplar dosya hattını okumayı göstermek

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

Okuma tamamlandıktan sonra bu otomatik olarak dosyayı kapatır mı? – Rohit

+3

Evet ve hayır - GzipReader bir dosya üzerinde doğrudan çalışıyorsa, kapatmak isteyebilirsiniz. Ama bu durumda, 'open' yönteminin dosyayı açtığını ve böylece 'inline' IO akışını kapatmanız gerektiğini varsaydım. – Tigraine

+2

Vay !! 4 yıl ve hala cevapla ilgili yorumları yanıtlıyor. Şimdi bu özveri! Tekrar teşekkürler. – Rohit

1

bu deneyin:

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

'while' işlevini kullanır, ancak @Tigraine'nin gösterildiği gibi 'each_line', Ruby'de daha deyimsizdir. –

+2

Biliyorum. Cevabımı sildiğimi bile düşündüm, ama sonra tamamen ayrılmaya karar verdim. –

+2

Bu iyi bir sebep. Bir şeyi başarmak için periyodik olarak alternatif yollar gösteriyorum. Ve bu Ruby'nin güzelliği, diğer dillerden öğrendiklerimize daha yakın olan stillere yazabiliriz, bu da programcılar olarak bizim için daha erişilebilir ve taşınabilir olmasını sağlar. Bu, Matz'in geliştirici için şeffaf olma hedefiyle uyumluydu. –

1

düzenli akışları (according to the docs) ile yapmak gibi gzip okuyucu üzerinde sadece döngü gerekir satır, ama sadece bir kez hataları yakalamak için değil. yani yalnızca benzersiz değerleri depolanır istasyonu gibi

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 

Seti eylemleri, ama Hash kullanılarak inşa edilmiştir, bu yüzden bir Hash gibi ama biz tuşlarıyla sadece endişeleriniz: Tigraine cevabı @ üzerinde bina. Çiftleri eklemeye çalışırsanız, atılırlar ve sizi yalnızca benzersiz değerlerle bırakırlar. Bir Array kullanabilir ve daha sonra üzerine uniq kullanın, ancak bir Set sizin önünüzde yönetecektir.

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