Bagaimana saya harus menggabungkan banyak file terkompresi menjadi satu arsip?

10

Saya memiliki beberapa ratus .tar.xzfile yang hampir identik (mereka adalah dump database harian, dan database berubah perlahan).

Saya percaya bahwa karena kesamaan dalam file yang tidak dikompresi, mereka akan memampatkan dengan sangat baik, dan tes skala kecil telah menunjukkan bahwa mengompresi sejumlah file yang tidak terkompresi ini membuat arsip hanya sedikit lebih besar dari salah satunya.

Masalah saya adalah bahwa semua file yang tidak terkompresi akan menjadi beberapa terabyte (rasio kompresi sekitar 25: 1), dan saya tidak memiliki banyak ruang disk untuk digunakan sebagai area kerja.

Apakah ada cara saya dapat memproses file terkompresi individu satu per satu, menambahkannya ke arsip tunggal dan mempertahankan manfaat dari mengompresi mereka bersama?

jl6
sumber
Sudahkah Anda mencoba scripting, sehingga Anda membuka kompres satu file, tambahkan semua file ke arsip yang diberikan dan kemudian pindah ke yang berikutnya?
darnir

Jawaban:

10

Karena file tar adalah format streaming - Anda dapat catmenggabungkan keduanya dan mendapatkan hasil yang hampir benar - Anda tidak perlu mengekstraknya ke disk sama sekali untuk melakukan ini. Anda dapat mendekompres (hanya) file, menggabungkannya bersama-sama, dan mengkompres ulang aliran itu:

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

combined.tar.xzakan menjadi tarball terkompresi dari semua file di tarbal komponen yang hanya sedikit rusak. Untuk mengekstrak, Anda harus menggunakan --ignore-zerosopsi (dalam GNU tar), karena arsip memiliki penanda "end-of-file" yang akan muncul di tengah-tengah hasil. Selain itu, semuanya akan bekerja dengan benar.

GNU tarjuga mendukung --concatenatemode untuk menghasilkan arsip gabungan. Itu memiliki batasan yang sama seperti di atas - Anda harus menggunakannya --ignore-zerosuntuk mengekstrak - tetapi itu tidak bekerja dengan arsip terkompresi. Anda dapat membangun sesuatu untuk mengelabui agar bekerja menggunakan substitusi proses, tetapi ini merepotkan dan bahkan lebih rapuh.

Jika ada file yang muncul lebih dari sekali di file tar yang berbeda, ini tidak akan berfungsi dengan baik, tetapi Anda tetap memiliki masalah itu. Kalau tidak, ini akan memberi Anda apa yang Anda inginkan - memipis keluaran xzadalah bagaimana tarmemampatkan outputnya.


Jika arsip yang hanya berfungsi dengan tarimplementasi tertentu tidak memadai untuk tujuan Anda, menambahkan ke arsip dengan radalah teman Anda:

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

Ini hanya mengekstraksi arsip tunggal pada satu waktu, sehingga ruang kerja terbatas pada ukuran konten arsip tunggal. Kompresi mengalir persis seperti seharusnya seandainya Anda membuat arsip terakhir sekaligus, sehingga akan sebaik yang pernah ada. Anda melakukan banyak dekompresi dan rekompresi berlebih yang akan membuat ini lebih lambat daripada catversi, tetapi arsip yang dihasilkan akan bekerja di mana saja tanpa dukungan khusus.

Perhatikan bahwa - tergantung pada apa yang sebenarnya Anda inginkan - cukup menambahkan file tar yang tidak dikompresi sendiri ke arsip mungkin sudah cukup. Mereka akan memampatkan (hampir) persis seperti halnya isinya dalam satu file, dan itu akan mengurangi overhead kompresi untuk setiap file. Ini akan terlihat seperti:

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

Ini sedikit kurang efisien dalam hal ukuran terkompresi akhir karena ada header tar tambahan dalam aliran, tetapi menghemat waktu untuk mengekstraksi dan menambahkan kembali semua file sebagai file. Anda akan berakhir dengan combined.tar.xzberisi banyak db-*.tarfile (tidak terkompresi) .

Michael Homer
sumber
Terima kasih, opsi kedua Anda terlihat tepat untuk tujuan saya, tetapi bisakah Anda menguraikan paragraf terakhir Anda? Akan seperti apa ini?
jl6
@ jl6: Lihat edit.
Michael Homer
Maaf, baru saja bisa menguji ini. Metode kedua Anda memberi saya kesalahan ini:tar: Cannot update compressed archives
jl6