Come XZ una directory con TAR utilizzando la massima compressione?


116

Quindi ho bisogno di comprimere una directory con la massima compressione.

Come posso farlo xz? Voglio dire che avrò bisogno taranche perché non riesco a comprimere una directory con solo xz. C'è un oneliner da produrre ad esempio foo.tar.xz?


11
FWIW, man 1 xzdice 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 per maggiori informazioni.
cychoi,

Risposte:


82

Supponendo che xzonori il set standard di flag della riga di comando - inclusi i flag del livello di compressione, puoi provare:

tar -cf - foo/ | xz -9 -c - > foo.tar.xz 

e questo utilizza il massimo livello di compressione con XZ?
LanceBaynes,

3
l'aggiunta di -9 a xz lo renderà massimo
bsd

23
-9eè il livello migliore, ma ci vorrà molto tempo
Krzysztof Krasoń

-9enon ti darà sempre il miglior risultato - vedi il punto 8 qui rootusers.com/13-simple-xz-examples
KolonUK

1
Inoltre, potresti aggiungere un miglioramento significativo se aggiungi --threads=0a xz
KolonUK il

146

Con una GNU recente tarsu bash o shell derivata:

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

L'opzione j minuscola di tar usa bzip, l'opzione j maiuscola usa xz.

La XZ_OPTvariabile di ambiente consente di impostare xzopzioni che non possono essere passate tramite applicazioni chiamanti come tar.

Questo è ora massimo .

Vedere man xzper altre opzioni che è possibile impostare ( -e/ --extreme potrebbe offrire alcuni vantaggi di compressione aggiuntivi per alcuni set di dati).

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

27
No, non lo fai. Questo è il punto. È possibile impostare l'ambiente var solo per quella chiamata. Puoi esportarlo se vuoi, ma non è necessario.
bsd

2
Stai assumendo una shell simile a bash per questo.
anddam,

7
@anddam, è supportato da tutte le shell della famiglia Bourne (Bourne, ksh, mksh, pdksh, ash, dash, bash, yash, zsh) e rce akanga. fish, csh, tcshE esdi essere i maggiori gusci che non lo supportano. Lì, useresti il envcomando.
Stéphane Chazelas,

1
Quindi, per impostare entrambe le opzioni -9e -exz, vuoi, XZ_OPT=-e9ma come ha sottolineato @krzyk, -e è estremamente lento
piani cottura

4
Solo per la cronaca: XZ_OPTnon è una funzionalità implementata in tar. È una caratteristica di xz. Quando tarchiama xz, la variabile env viene semplicemente trasmessa.
Sven,

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

è persino meglio di

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

5
Come va meglio? Cosa fa la bandiera elettronica?
cxdf,

2
option -e, --extremeModifica la preimpostazione della compressione (-0 ... -9) in modo da ottenere un rapporto di compressione leggermente migliore senza aumentare l'utilizzo della memoria del compressore o del decompressore (eccezione: l'utilizzo della memoria del compressore può aumentare leggermente con le preimpostazioni -0 ... -2). Il rovescio della medaglia è che il tempo di compressione aumenterà notevolmente (può facilmente raddoppiare).
Evandro Jr,

Quindi, se sto comprimendo circa 80 GB di software sulla mia macchina (quando voglio che tutte le risorse del computer vadano al processo di compressione per velocità) -9non dovrei usare -9e, sì?
nyxee,

1
xz usa di default 1 core / thread, puoi massimizzare (velocizza tutto) aggiungendo -T0, ad es.XZ_OPT="-9e -T0" tar -cJf ...
EkriirkE

10

Se hai 16 GiB di RAM (e nient'altro in esecuzione), puoi provare:

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

Ciò richiederà 1,5 GiB per la decompressione e circa 11 volte quello per la compressione. Regolare di conseguenza per minori quantità di memoria.

Questo aiuterà solo se i dati sono in realtà così grande, e in ogni caso non aiuterà CHE molto, ma ancora ...

Se stai comprimendo i binari, aggiungi --x86 come prima opzione xz. Se stai giocando con file "multimediali" (audio non compresso o bitmap), puoi provare con --delta = dist = 2 (sperimenta con il valore, i buoni valori da provare sono 1..4).

Se ti senti molto avventuroso, puoi provare a giocare con più opzioni LZMA, come

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

(queste sono le impostazioni predefinite, puoi provare valori compresi tra 0 e 4 e lc + lp non deve superare 4)

Per vedere come i preset predefiniti sono associati a questi valori, è possibile controllare il file sorgente src / liblzma / lzma / lzma_encoder_presets.c. Non c'è nulla di molto interessante lì (-e imposta la bella lunghezza su 273 e regola anche la profondità).


6

Potresti provare diverse opzioni, per me -4e funziona meglio

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

Ho provato eseguendo:

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

Quindi, sembra che l'opzione -4e funzioni un po 'meglio di -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

3
Questo in realtà non risponde alla domanda. Questa è solo un'osservazione che per il tuo particolare set di dati di piccole dimensioni, -4e ottiene già la migliore compressione e quindi i livelli più alti non ottengono alcun vantaggio (e persino una penalità sempre così lieve).
psusi,

Sei lo stesso utente di Szymon Roziewski ? In tal caso, non pubblicare più risposte. Invece, modifica la risposta originale. Se non riesci ad accedere al tuo primo account, vedi qui per come unire i tuoi account. Nel frattempo, sto eliminando la tua risposta precedente e la includo qui.
terdon

Ok, ho fatto uno studio più completo su questo. Quello che ho è qui. Ho scelto alcuni file dal mio hardrive e ho fatto la compressione con l'opzione -4e e -9e. Quindi, è meglio trovare la soluzione migliore da soli. Avevi ragione, per alcuni casi -9e è meglio, mentre per altri no: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,

(i commenti possono essere modificati solo per 5 minuti)txt 109 txt/pdf 135
Szymon Roziewski il

2
+1. Questo aiuta l'OP a trovare un modo per determinare la massima compressione per tarl'utilizzo dei 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/    

comprimere anche con compressori esterni:

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

decomprimere i compressori esterni:

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

lista archivio compressori esterni:

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

1
Questa sembra una risposta funzionante, ma, così com'è, sarebbe notevolmente migliorata con la formattazione fissa e la spiegazione dell'opzione -Iaggiunta.
Dhag,

4

taril comando usa Jflag per i file xz. Un esempio:

tar -cJvf foo.tar.xz foo/


2
La cosa Jera già menzionata nella risposta del bdowning
Anthon,

3

Per gli interessati, -e9è dello 0,4% più piccolo, del 20% più lento a compressione, del 3% più lento per la decompressione, rispetto a -9un normale laptop. Ecco i tempi di esecuzione sulla struttura della directory del codice sorgente di Python.

Compressione:

$ 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

Decompressione:

$ 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

Dimensione del 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

1
Scelta del nome della variabile errata, poiché T0 è un'opzione per abilitare l'archiviazione multi-thread.
Dzenly

@Dzenly Hai ragione! Grazie! Modificato
Piani cottura

2

Questa non è una risposta esatta alla tua domanda ma potresti usare un comando invece di due:

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

aggiunge tutti i file dalla directory "dir1" all'archivio archive.7z usando "ultras ettings"

altri formati supportati sono: zip, gzip, bzip2 o tar. per questo basta sostituire 7zdopo -t.
--fonteman 7z

NOTA: non utilizzare questo comando per eseguire il backup dei file di sistema tranne i file personali poiché il formato 7z non memorizza le autorizzazioni del file system .


5
La domanda era su xz, non su 7z, anche se entrambi usano la compressione LZMA.
Amedee Van Gasse,

2

In una macchina multicore dalla versione v5.2.0 di xz-utils, controllare:

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

Se si desidera utilizzare il numero massimo di core e la massima compressione:

export XZ_DEFAULTS="-9 -T 0 "

Oppure imposta -T sul numero di core che desideri utilizzare.

Poi:

tar cJf target.tar.xz source

Anche questo può essere utile per scegliere il livello di compressione:

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


1

Se desideri che questo si completi più velocemente, usando più thread, ma senza rallentare il tuo sistema mentre esegui altri lavori, prova ad aggiungere -Tndove n è quanti thread vuoi usare, oltre nicea ridurre la compressione a priorità inattiva.

Modello (per 4 fili):

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

Prova a guardare in topo htopquando lo fai in una grande directory (diversi GB). Si spera che dovresti vedere diversi xzthread con un valore di 19 (priorità più bassa).

Ho anche messo a tacere questa frase sia tanto concisa quanto sensata, come ad esempio: le -f -altre risposte non sono semplicemente necessarie, poiché tarl'output predefinito è stdout.

Puoi anche eseguire niceil processo tar, ma non l'ho mai trovato necessario, come xzsempre colli di bottiglia della CPU per la pipeline.

Nota pratica, uso raramente xz -9per nulla, non tanto a causa della CPU o del tempo, ma a causa delle elevate esigenze di memoria. Dai un'occhiata a https://catchchallenger.first-world.info/wiki/Quick_Benchmark:_Gzip_vs_Bzip2_vs_LZMA_vs_XZ_vs_LZ4_vs_LZO#Memory_requirements_on_compression . Il xzcompressore, come bzip2, ma a differenza gzip, utilizza più memoria per fattori di compressione più elevati. Metti insieme che xzutilizza molta più memoria rispetto a qualsiasi altro compressore, puoi facilmente utilizzare fino a 600+ MB di memoria. E se si utilizza il -Tper abilitare la compressione filettata, le richieste di memoria aumentano ulteriormente. Solo qualcosa di cui tenere conto, come se si eseguisse un piccolo servizio su una piccola VM con 1-2 GB di memoria, si potrebbe inavvertitamente causare un impatto.


1

Su Mac OS X, un approccio alternativo con cui passare il parametro tarè l'uso di un --options=flag. Per esempio,

tar Jcvf targetFileName.tar.xz --options='compression-level=9' directoryName
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.