ファイル全体を解凍せずに大容量のgzipファイルの最初の行を変更するには?

ファイル全体を解凍せずに大容量のgzipファイルの最初の行を変更するには?

現在、A.gz最初の行のヘッダーを含む多くの表形式のデータを含む圧縮ファイルがあります。B.gz以前のファイルとデータは同じですが、異なるヘッダーを持つ別のファイルを作成したいと思います。

これを行う簡単な方法は、最初の行を除くすべての項目を解凍し、A.gz-ingtailしてからすべての項目を再圧縮することです。しかし、これは非常に非効率的なようです。特に、2つの-edファイルをリンクすると、gzip解凍されたバージョンの接続で正しく解凍されるためです。

次の方法があるかどうか疑問に思います。

zcat A.gz | head -n 1 | process_header | gzip > B.gz
cat A.gz | (remove compressed header) >> B.gz

すべてのコンテンツを解凍する必要はありませんA.gz

答え1

一番上に別の行を挿入したい場合は簡単です。

echo some line | gzip > newfile.gz
cat newfile.gz oldfile.gz > result.gz

gzip は接続を許可します。解凍せずにファイルを見るだけで、間違った圧縮されていないファイルサイズが報告されるのが気に入らない場合、つまり、そうです。また、一部のプログラムではWinRARなどのファイルを処理できません。

実際に望むものに近づくための質問は、gzipファイルが互いに完全に独立して実行されるチャンクで構成されているかどうか、それでチャンク境界を見つける方法です。

これを行い、2つの別々のgzipファイルをリンクしてgzipを作成したい場合は簡単に解決できますが、任意のgzipファイルを使用してこれを行うには、gzipファイル形式のより深い理解が必要です。

以前のすべてを解凍せずに特定のオフセットに直接アクセスできるbzip2ブロックマップを生成したbzip2プログラム(名前は忘れました)があったことを覚えています。

しかし、結局のところ、ほとんどの人は再び圧縮します。とにかくファイル全体を書き換えることを避けることはできません。したがって、成功するといくつかのCPUサイクルを節約できますが、時間はありません。


問題に対する解決策ではありませんが...最初の行を削除するgzipために使用しないでください。おそらく、aまたは他のものと比較して非常に非効率的です。最初の行を削除するためにファイル内のすべての行を数える必要はありません。tailsed 1d

答え2

どうですか?

zcat A.gz | awk '{if(NR==1){print "myheader"}else{print $0}}' | gzip > B.gz

NR(レコード番号)が1の場合、自分だけのヘッダーを出力します。他のすべての行はそのまま残します。

答え3

!!!これは単なる考えです!

あなたは実行を試すことができます

zcat file | head -n100 > tempfile 
vim tempfile # edit the file header
cat tempfile | gzip | dd of=B.gz conv=notrunc

これにより、圧縮されたファイルから最初の100行だけ抽出され、それが再圧縮され、B.gzファイルeの同じブロックがきめ細かく上書きされます。

問題は、これが確認する必要がある実際の解決策ではないことです。今後そして後ろにデータは同じバイト数を消費し、ファイルを繰り返し、CRC32新しいファイルを計算してファイルフッターに書き込みます。

あなたが答える方が良いかもしれません。スティーブあなたのため。

答え4

それでも解凍されますが、大容量ファイルの場合はzcatやgzipよりはるかに高速です。

pigz -dc new_header.txt.gz A.gz | sed '2d' | pigz > B.gz

上記のコマンドを実行する前に、新しいヘッダーnew_header.txt(改行なし)を入れてgzipで圧縮するだけです。

関連情報