複数の圧縮ファイルを1つのアーカイブにマージする方法は?

複数の圧縮ファイルを1つのアーカイブにマージする方法は?

ほぼ同じファイルが何百ものあります.tar.xz(毎日データベースがダンプされ、データベースがゆっくりと変更されます)。

私は圧縮されていないファイルの類似性のために圧縮がうまくいくと思います。小規模なテストでは、これらの圧縮されていないファイルを必要なだけ圧縮すると、そのうちの1つより少し大きいアーカイブが生成されることがわかりました。

私の問題は、圧縮されていないすべてのファイルが数テラバイト(圧縮率は約25:1)になり、ワークスペースとして使用するディスク容量がそれほど多くないことです。

個々の圧縮ファイルを一度に1つずつ処理して単一のアーカイブに追加し、一緒に圧縮する利点を維持する方法はありますか?

ベストアンサー1

tarファイルはストリーミング形式なので、cat2つを一緒に使用するとほぼ正確な結果が得られます。これを行うためにディスクに取り出す必要はありません。ファイルを解凍して一緒にリンクしてからストリームを再圧縮するだけです。

xzcat *.tar.xz | xz -c > combined.tar.xz

combined.tar.xzアセンブリターボールのすべてのファイルが圧縮されたターボールになり、わずかに破損しています。抽出するには、以下を使用する必要があります。--ignore-zerosオプション(GNUではtar)アーカイブには「ファイルの終わり」マークがあるため、結果の途中に表示されます。しかし、それ以外はすべてうまくいくでしょう。

GNUtarもサポート--concatenate結合されたアーカイブを作成するためのパターン。上記と同じ制限があります。解凍するにはそれを使用する必要があります--ignore-zeros。ただし、圧縮アーカイブでは機能しません。プロセス置換を使用して動作するように欺く何かを作成できますが、これは面倒で、はるかに脆弱です。

一部のファイルが他のtarファイルに複数回表示される場合は機能しませんが、とにかく問題が発生します。そうでなければ、欲しいものを手に入れることができます。出力をパイプすることは、出力を圧縮する方法xzです。tar


特定tarの実装のみのアーカイブが目的に十分でない場合は、r以下をアーカイブに追加できます。

tar cJf combined.tar.xz dummy-file
for x in db-*.tar.xz
do
    mkdir tmp
    pushd tmp
    tar xJf "../$x"
    tar rJf ../combined.tar.xz .
    popd
    rm -r tmp
done

一度に1つのアーカイブしか抽出できないため、ワークスペースは単一のアーカイブのコンテンツサイズに制限されます。まるで最終アーカイブを一度に作成するかのように圧縮がストリーミングされるため、以前と同じになります。過度に解凍して再圧縮することは多くあり、バージョンよりも遅くなりますが、結果のcatアーカイブは特別なサポートなしでどこでも機能します。

特定の要件に応じて、圧縮されていないtarファイル自体をアーカイブに追加するだけで十分です。単一ファイルの内容を(ほぼ)完全に圧縮し、ファイル固有の圧縮オーバーヘッドを減らします。これは次のとおりです。

tar cJf combined.tar.xz dummy-file
for x in db-*.tar.xz
do
    xz -dk "$x"
    tar rJf combined.tar.xz "${x%.xz}"
    rm -f "${x%.xz}"
done

ストリームの追加のtarヘッダーは最終的な圧縮サイズの点で効率をわずかに低下させますが、すべてのファイルを抽出してファイルに再追加するのに時間を節約します。結局、combined.tar.xz多くの(圧縮されていない)db-*.tarファイルが生成されます。

おすすめ記事