web-dev-qa-db-ja.com

圧縮されたテキストファイルの最後の数行を解凍して印刷するにはどうすればよいですか?

6つのgzip圧縮されたテキストファイルがあり、それぞれ圧縮すると〜17Gになります。特定の問題が存在するかどうかを確認するには、各ファイルの最後の数行(解凍)を確認する必要があります。明らかなアプローチは非常に遅いです:

for i in *; do zcat "$i" | tail -n3; done

私は次のような賢いことができると思っていました:

for i in *; do tail -n 30 "$i" | gunzip | tail -n 4 ; done

または

for i in *; do tac "$i" | head -100 | gunzip | tac | tail -n3; done

しかし、両方とも不満があります:

gzip: stdin: not in gzip format

gzipヘッダーがないためだと思いましたが、これも失敗します。

$ aa=$(head -c 300 file.gz)
$ bb=$(tail -c 300 file.gz)
$ printf '%s%s' "$aa" "$bb" | gunzip
gzip: stdin: unexpected end of file

私が実際に探しているのはztailまたはztacですが、それらは存在しないと思います。誰でも、圧縮ファイルの最後の数行を解凍せずに解凍して印刷できる巧妙なトリックを思いつくことができますか?

6
terdon

ファイルが標準のgzipで圧縮されている場合、それはできません すでに述べられています 。圧縮を制御できる場合は、 dictzip を使用してファイルを圧縮できます。ファイルを個別のブロックに圧縮し、最後のブロック(通常は64KB)のみを解凍できます。また、gzipとの下位互換性があります。つまり、dictzippedファイルは完全に正当なgzipファイルです。

他の可能性としては、gzip圧縮されたファイルをいくつかのgzip圧縮されたファイルの連結として取得した場合、最後のgzip署名を検索し、その後すべてを解凍できます。

7

さて、以前に各ファイルにindexを作成した場合、できますgzip圧縮ファイルにランダムにアクセスできます。 。

私はあなたがおそらく探していたコマンドラインツールを開発しました:それはgunzipと同じ時間を使って尾にアクセスできます...しかし、それは少し(<< 1%/ gzip)のインデックスを作成するため、次の抽出は本当に速いでしょう

https://github.com/circulosmeos/gztool

このツールには、次の2つのオプションがあります。

  • -Sオプションは、まだ成長しているファイルを監視し、成長するにつれてそのインデックスを作成します-これは、gzip圧縮されたrsyslogファイルが0になるため便利です実際には、インデックス作成時。
  • -tgzipファイルの末尾:この方法で実行できます:$ gztool -t foo.gzインデックスが存在しない場合、これは完全な解凍と同じ時間を消費することに注意してください。ただし、インデックスが再利用可能であるため、次の検索は時間を大幅に短縮されます。それを使用しないで、同時にインデックスを作成しますか?

このツールは 元のzlibからのzran.cデモコード に基づいているため、ルール外の魔法はありません。

3
circulosmeos