Bagaimana cara XZ direktori dengan TAR menggunakan kompresi maksimum?

116

Jadi saya perlu mengkompres direktori dengan kompresi maksimal.

Bagaimana saya bisa melakukannya xz? Maksud saya, saya perlu tarjuga karena saya tidak dapat mengompres direktori dengan hanya xz. Apakah ada oneliner untuk diproduksi misalnya foo.tar.xz?

LanceBaynes
sumber
11
FWIW, man 1 xzkata it's not a good idea to blindly use -9 for everything like it often is with gzip(1) and bzip2(1). -7 ... -9 [...] These are useful only when compressing files bigger than 8 MiB, 16 MiB, and 32 MiB, respectively.RTFM untuk info lebih lanjut.
cychoi

Jawaban:

82

Dengan asumsi xzmenghormati set standar flag commandline - termasuk flag level kompresi, Anda dapat mencoba:

tar -cf - foo/ | xz -9 -c - > foo.tar.xz 
Shadur
sumber
dan ini menggunakan level kompresi maksimum dengan XZ?
LanceBaynes
3
menambahkan -9 ke xz akan membuatnya maks
bsd
23
-9eadalah level terbaik, tetapi itu akan memakan waktu sangat lama
Krzysztof Krasoń
-9etidak akan selalu memberi Anda hasil terbaik - lihat poin 8 di sini rootusers.com/13-simple-xz-examples
KolonUK
1
Juga, Anda mungkin melihat peningkatan yang signifikan jika Anda menambahkan --threads=0ke xz
KolonUK
146

Dengan GNU baru-baru ini tardi bash atau shell yang diturunkan:

XZ_OPT=-9 tar cJf tarfile.tar.xz directory

sakelar j huruf kecil tar menggunakan bzip, sakelar J huruf besar menggunakan xz.

The XZ_OPTvariabel lingkungan memungkinkan Anda mengatur xzopsi yang tidak dapat dilewatkan melalui memanggil aplikasi seperti tar.

Ini sekarang sudah maksimal .

Lihat man xzopsi lain yang dapat Anda atur ( -e/ --extreme mungkin memberi Anda beberapa manfaat kompresi tambahan untuk beberapa dataset).

XZ_OPT=-e9 tar cJf tarfile.tar.xz directory
bsd
sumber
27
Tidak, tidak. Itulah intinya. Anda dapat mengatur var lingkungan hanya untuk permohonan itu. Anda dapat mengekspornya jika mau, tetapi tidak harus.
bsd
2
Anda mengasumsikan shell seperti bash untuk itu.
anddam
7
@ anddam, itu didukung oleh semua cangkang dari keluarga Bourne (Bourne, ksh, mksh, pdksh, ash, dash, bash, yash, zsh) dan rcdan akanga. fish, csh, tcshDan esmenjadi kerang besar yang tidak mendukungnya. Di sana, Anda akan menggunakan envperintah.
Stéphane Chazelas
1
Jadi untuk mengatur kedua -9dan -exz opts, Anda inginkan XZ_OPT=-e9tetapi seperti yang ditunjukkan @krzyk, -e sangat lambat
hobs
4
Sebagai catatan: XZ_OPTbukan fitur yang diterapkan di tar. Ini fitur dari xz. Ketika tarpanggilan xz, variabel env hanya diteruskan.
Sven
14
XZ_OPT=-9e tar cJf tarfile.tar.xz directory

bahkan lebih baik daripada

XZ_OPT=-9 tar cJf tarfile.tar.xz directory
Evandro Jr
sumber
5
Bagaimana ini lebih baik? Apa yang dilakukan flag e?
cxdf
2
option -e, --extremeUbah preset kompresi (-0 ... -9) sehingga rasio kompresi sedikit lebih baik dapat dicapai tanpa meningkatkan penggunaan memori kompresor atau dekompresor (pengecualian: penggunaan memori kompresor dapat meningkat sedikit dengan preset -0 ... -2). Kelemahannya adalah bahwa waktu kompresi akan meningkat secara dramatis (dapat dengan mudah berlipat ganda).
Evandro Jr
Jadi, jika saya mengompres sekitar 80GB Perangkat Lunak pada mesin saya (ketika saya ingin semua sumber daya komputer untuk pergi ke proses kompresi untuk kecepatan) saya harus menggunakan -9tidak -9e, ya?
nyxee
1
xz secara default menggunakan 1 inti / utas, Anda dapat memaksimalkannya (mempercepat semuanya) dengan menambahkan -T0, misalnyaXZ_OPT="-9e -T0" tar -cJf ...
EkriirkE
10

Jika Anda memiliki 16 GiB RAM (dan tidak ada yang berjalan), Anda dapat mencoba:

tar -cf - foo/ | xz --lzma2=dict=1536Mi,nice=273 -c - > foo.tar.xz 

Ini akan membutuhkan 1,5 GiB untuk dekompresi, dan sekitar 11xb untuk kompresi. Sesuaikan dengan itu untuk jumlah memori yang lebih sedikit.

Ini hanya akan membantu jika data sebenarnya yang besar, dan dalam hal apapun tidak akan membantu BAHWA banyak, tapi masih ...

Jika Anda mengompresi binari, tambahkan --x86 sebagai opsi xz pertama. Jika Anda bermain dengan file "multimedia" (audio atau bitmap yang tidak terkompresi), Anda dapat mencoba dengan --delta = dist = 2 (percobaan dengan nilai, nilai yang baik untuk dicoba adalah 1..4).

Jika Anda merasa sangat suka berpetualang, Anda bisa mencoba bermain dengan lebih banyak opsi LZMA

--lzma2=dict=1536Mi,nice=273,lc=3,lp=0,pb=2

(ini adalah pengaturan default, Anda dapat mencoba nilai antara 0 dan 4, dan lc + lp tidak boleh melebihi 4)

Untuk melihat bagaimana preset default memetakan nilai-nilai ini, Anda dapat memeriksa file sumber src / liblzma / lzma / lzma_encoder_presets.c. Tidak ada yang menarik di sana (-e menetapkan panjang yang bagus untuk 273 dan juga menyesuaikan kedalaman).

Anonim, tanpa nama
sumber
6

Anda dapat mencoba berbagai opsi, karena saya -4e berfungsi lebih baik

tar cf - wam_GG_${dir}.nc | xz -4e > wam_GG_${dir}.nc.tar.xz 

Saya diuji dengan menjalankan:

$ tar -cf - wam_GG.nc | xz -4e > wam_GG.nc.xz
$ tar -cf - wam_GG.nc | xz -9e > wam_GG.nc.xz.2

Jadi, tampaknya opsi -4e bekerja sedikit lebih baik daripada -9e.

$ ll wam_GG.nc.xz*
-rw-rw-r--. 1 504 504 2707596 Jan 16  2015 wam_GG.nc.xz
-rw-rw-r--. 1 504 504 2708416 Jan 16  2015 wam_GG.nc.xz.2
Szymon Roziewski
sumber
3
Ini benar-benar tidak menjawab pertanyaan. Ini hanya sebuah pengamatan bahwa untuk kumpulan data kecil Anda, -4e sudah mendapatkan kompresi terbaik sehingga level yang lebih tinggi tidak mendapatkan manfaat lebih (dan bahkan penalti yang sangat kecil).
psusi
Apakah Anda pengguna yang sama dengan Szymon Roziewski ? Jika demikian, jangan posting beberapa jawaban. Alih-alih, edit jawaban asli Anda. Jika Anda tidak dapat mengakses akun pertama Anda, silakan lihat di sini untuk cara menggabungkan akun Anda. Sementara itu, saya menghapus jawaban Anda sebelumnya dan memasukkannya di sini.
terdon
Ok, saya sudah melakukan studi yang lebih komprehensif tentang itu. Apa yang saya dapatkan ada di sini. Saya memilih beberapa file dari hardrive saya dan melakukan kompresi dengan opsi -4e dan -9e. Jadi, lebih baik untuk menemukan solusi terbaik Anda sendiri. Anda benar, untuk beberapa kasus -9e lebih baik sedangkan untuk yang lain itu tidak:no difference = 660 4e better than 9e = 74 9e better than 4e = 17 total files = 751 tar 2 html 2 csv 2 xml 2 gz 2 ppt 2 eps 2 docx 2 gif 2 rpm 3 png 3 asv 3 xlsx 3 exe 3 rar 4 nc 4 txt 5 odt 6 xls 7 zip 7 doc 9 m 12 dat 17 other 109 pdf 133 135 jpg 270
Szymon Roziewski
(komentar dapat diedit hanya selama 5 menit)txt 109 txt/pdf 135
Szymon Roziewski
2
+1. Ini membantu OP menemukan cara untuk menentukan kompresi maksimum untuk tarmenggunakan file xz.
cychoi
5

tar --help : -I, --use-compress-program=PROG

tar -I 'xz -9' -cvf foo.tar.xz foo/  
tar -I 'gzip -9' -cvf foo.tar.gz foo/    

juga kompres dengan kompresor eksternal:

tar -I 'lz4 -9' -cvf foo.tar.lz4 foo/
tar -I 'zstd -19' -cvf foo.tar.zst foo/

dekompresi kompresor eksternal:

tar -I lz4 -xvf foo.tar.lz4  
tar -I zstd -xvf foo.tar.zst  

daftar arsip kompresor eksternal:

tar -I lz4 -tvf foo.tar.lz4
tar -I zstd -tvf foo.tar.zst
Goran Dragic
sumber
1
Ini sepertinya jawaban yang berfungsi, tetapi, sebagaimana adanya, itu akan sangat ditingkatkan dengan memperbaiki pemformatannya dan penjelasan opsi yang -Iditambahkan.
Dhag
4

tarperintah menggunakan Jflag untuk file xz. Sebuah contoh:

tar -cJvf foo.tar.xz foo/

leonardoav
sumber
2
Itu Jsudah disebutkan dalam jawaban bdowning
Anthon
3

Bagi mereka yang tertarik, -e9adalah 0,4% lebih kecil, 20% lebih lambat pada kompresi, 3% lebih lambat untuk dekompresi, dibandingkan dengan -9pada laptop biasa. Di sini waktunya berjalan pada struktur direktori kode sumber Python.

Kompresi:

$ Tbefore=`date +%s%3N` && XZ_OPT=-9 tar cJf python3.6.tar.9xz Python-3.6.0 && Tafter=`date +%s%3N`
$ python -c "print((float($Tafter) - float($Tbefore)) / 1000.)"
43.87
$ Tbefore=`date +%s%3N` && XZ_OPT=-e9 tar cJf python3.6.tar.e9xz Python-3.6.0 && Tafter=`date +%s%3N`
$ python -c "print((float($Tafter) - float($Tbefore)) / 1000.)"
53.861

Dekompresi:

$ Tbefore=`date +%s%3N` && tar xf python3.6.tar.9xz && Tafter=`date +%s%3N`
$ python -c "print((float($Tafter) - float($Tbefore)) / 1000.)"  && rm -rf Python-3.6.0
1.395
$ rm -rf Python-3.6.0
$ Tbefore=`date +%s%3N` && tar xf python3.6.tar.e9xz && Tafter=`date +%s%3N`
$ python -c "print((float($Tafter) - float($Tbefore)) / 1000.)"  && rm -rf Python-3.6.0
1.443

Ukuran file:

$ rm -rf Python-3.6.0
$ Tbefore=`date +%s%3N` && tar xf Python-3.6.0.tar.xz && Tafter=`date +%s%3N`
$ python -c "print((float($Tafter) - float($Tbefore)) / 1000.)" && rm -rf Python-3.6.0
1.49
$ ls -al ?ython*
-rw-rw-r-- 1 hobs hobs 16378500 Dec 23 13:06 python3.6.tar.9xz
-rw-rw-r-- 1 hobs hobs 16314420 Dec 23 13:05 python3.6.tar.e9xz
-rw-rw-r-- 1 hobs hobs 16805836 Dec 23 12:24 Python-3.6.0.tar.xz
hobs
sumber
1
Memilih nama variabel yang salah, karena T0 adalah opsi untuk mengaktifkan pengarsipan multi-utas.
Dzenly
@Dzenly Anda benar! Terima kasih! Mengubahnya.
Hobs
2

Ini bukan jawaban yang tepat untuk pertanyaan Anda, tetapi Anda bisa menggunakan satu perintah, bukan dua:

7z a -t7z -m0=lzma -mx=9 -mfb=64 -md=32m -ms=on archive.7z dir1

menambahkan semua file dari direktori "dir1" ke arsip archive.7z menggunakan "ultras ettings"

format lain yang didukung adalah: zip, gzip, bzip2 atau tar. untuk ini ganti saja 7zsetelahnya -t.
--sumberman 7z

CATATAN: jangan gunakan perintah ini untuk membuat cadangan file sistem Anda kecuali file pribadi karena format 7z tidak menyimpan izin sistem file .

Edward Torvalds
sumber
5
Pertanyaannya adalah tentang xz, bukan tentang 7z, meskipun mereka berdua menggunakan kompresi LZMA.
Amedee Van Gasse
2

Di mesin multicore dari versi v5.2.0 dari xz-utils, periksa:

-T, --threads=NUM   use at most NUM threads; the default is 1; set to 0

Jika Anda ingin menggunakan jumlah core dan kompresi maksimum:

export XZ_DEFAULTS="-9 -T 0 "

Atau atur -T ke jumlah core yang ingin Anda gunakan.

Kemudian:

tar cJf target.tar.xz source

Ini juga berguna untuk memilih tingkat kompresi:

https://catchchallenger.first-world.info/wiki/Quick_Benchmark:_Gzip_vs_Bzip2_vs_LZMA_vs_XZ_vs_LZ4_vs_LZO

mirix
sumber
1

Jika Anda ingin ini diselesaikan lebih cepat, menggunakan beberapa utas, tetapi tanpa memperlambat sistem Anda saat Anda melakukan pekerjaan lain, coba tambahkan di -Tnmana n adalah berapa banyak utas yang ingin Anda gunakan, serta niceuntuk menurunkan kompresi untuk prioritas siaga.

Model (untuk 4 utas):

tar c foo/ | nice -n19 xz -9 -T4 > foo.tar.xz

Coba tonton topatau htopketika Anda melakukan ini di direktori besar (beberapa GB). Mudah-mudahan Anda akan melihat beberapa xzutas dengan nilai Nice 19 (prioritas terendah).

Saya juga telah menanggalkan ini -f -sesederhana yang masuk akal, seperti: di jawaban lain sama sekali tidak diperlukan, karena tarkeluaran default adalah stdout.

Anda dapat niceproses tar juga, tetapi saya tidak pernah merasa perlu, karena xzselalu bottleneck CPU untuk pipa.

Catatan praktis, saya jarang menggunakan xz -9apa pun, bukan karena CPU atau waktu, tetapi karena tuntutan memori yang tinggi. Lihatlah https://catchchallenger.first-world.info/wiki/Quick_Benchmark:_Gzip_vs_Bzip2_vs_LZMA_vs_XZ_vs_LZ4_vs_LZO#Memory_requirements_on_compression . The xzkompresor, seperti bzip2, tapi tidak seperti gzip, menggunakan lebih banyak memori untuk faktor kompresi yang lebih tinggi. Masukkan itu bersama dengan yang xzmenggunakan memori jauh lebih banyak daripada kompresor lainnya, Anda dapat dengan mudah menggunakan memori lebih dari 600 MB. Dan jika Anda menggunakan -Tuntuk mengaktifkan kompresi berulir, tuntutan memori naik lebih jauh. Hanya sesuatu yang perlu diperhatikan, seperti jika Anda menjalankan beberapa layanan kecil pada VM kecil dengan memori 1-2 GB, Anda dapat secara tidak sengaja menyebabkan dampak.

Joshua Huber
sumber
1

Pada Mac OS X, pendekatan alternatif untuk meneruskan parameter dengan taradalah dengan menggunakan --options=flag. Sebagai contoh,

tar Jcvf targetFileName.tar.xz --options='compression-level=9' directoryName
Samuel Li
sumber