Wie XZ ein Verzeichnis mit TAR mit maximaler Komprimierung?

116

Also muss ich ein Verzeichnis mit maximaler Komprimierung komprimieren.

Wie kann ich das machen xz? Ich meine, ich werde auch brauchen, tarweil ich ein Verzeichnis nicht nur mit komprimieren kann xz. Gibt es einen Oneliner zum Beispiel zu produzieren foo.tar.xz?

LanceBaynes
quelle
11
FWIW, man 1 xzsagt 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 für weitere Informationen.
Cychoi

Antworten:

82

Unter xzder Annahme, dass der Standardsatz von Befehlszeilenflags eingehalten wird - einschließlich Flags für die Komprimierungsstufe - können Sie Folgendes versuchen:

tar -cf - foo/ | xz -9 -c - > foo.tar.xz 
Shadur
quelle
und dies nutzt maximale Komprimierungsstufe mit XZ?
LanceBaynes
3
Hinzufügen von -9 zu xz macht es max
bsd
23
-9eist das beste Level, aber es wird sehr lange dauern
Krzysztof Krasoń
-9eliefert
KolonUK
1
Außerdem könnten Sie eine deutliche Verbesserung --threads=0
feststellen,
146

Mit einer aktuellen GNU tarauf Bash oder abgeleiteten Shell:

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

Tars J-Schalter in Kleinbuchstaben verwendet bzip, der J-Schalter in Großbuchstaben verwendet xz.

Mit der XZ_OPTUmgebungsvariablen können Sie xzOptionen festlegen , die nicht über aufrufende Anwendungen wie z tar.

Das ist jetzt maximal .

Siehe man xzweitere Optionen können Sie einstellen ( -e/ --extreme könnte Ihnen einige zusätzliche Kompression Nutzen für einige Datensätze).

XZ_OPT=-e9 tar cJf tarfile.tar.xz directory
bsd
quelle
27
Nein, tust du nicht. Das ist der springende Punkt. Sie können die Umgebungsvariable nur für diesen Aufruf festlegen. Sie können es exportieren, wenn Sie möchten, müssen es aber nicht.
bsd
2
Du nimmst dafür eine bash-artige Hülle an.
anddam
7
@anddam, das wird von allen Shells der Bourne-Familie unterstützt (Bourne, ksh, mksh, pdksh, ash, dash, bash, yash, zsh) und rcund akanga. fish, csh, tcshUnd esdie großen Schalen ist , dass sie nicht unterstützen. Dort würden Sie den envBefehl verwenden.
Stéphane Chazelas
1
Also beide setzen -9und -exz entscheidet, wollen Sie XZ_OPT=-e9aber als @krzyk wies darauf hin, -e ist extrem langsam
Wälzfräser
4
Nur zur Veranschaulichung: XZ_OPTIst kein Feature implementiert in tar. Es ist ein Merkmal von xz. Beim tarAufruf xzwird die env-Variable einfach weitergereicht.
Sven
14
XZ_OPT=-9e tar cJf tarfile.tar.xz directory

ist noch besser als

XZ_OPT=-9 tar cJf tarfile.tar.xz directory
Evandro Jr
quelle
5
Wie ist das besser Was macht die e-Flagge?
cxdf
2
option -e, --extremeÄndern Sie die Komprimierungsvorgabe (-0 ... -9), damit ein etwas besseres Komprimierungsverhältnis erzielt werden kann, ohne die Speichernutzung des Kompressors oder Dekomprimierers zu erhöhen (Ausnahme: Die Speichernutzung des Kompressors kann mit den Vorgaben -0 ... -2). Der Nachteil ist, dass sich die Komprimierungszeit drastisch erhöht (sie kann sich leicht verdoppeln).
Evandro Jr.
Also, wenn ich ungefähr 80 GB Software auf meinem Computer komprimiere (wenn ich möchte, dass alle Computer-Ressourcen schnell komprimiert werden), sollte ich das -9nicht verwenden -9e, ja?
Nyxee
1
xz verwendet standardmäßig 1 Core / Thread. Sie können dies durch Hinzufügen von -T0 XZ_OPT="-9e -T0" tar -cJf ...
maximieren
10

Wenn Sie 16 GB RAM haben (und nichts anderes läuft), können Sie versuchen:

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

Für die Dekomprimierung werden 1,5 GiB benötigt, für die Komprimierung etwa das 11-fache. Passen Sie dies bei geringerem Speicherbedarf entsprechend an.

Dies wird helfen , nur dann , wenn die Daten tatsächlich so groß ist, und in jedem Fall wird es nicht helfen , DASS viel, aber immer noch ...

Wenn Sie Binärdateien komprimieren, fügen Sie --x86 als erste xz-Option hinzu. Wenn Sie mit "Multimedia" -Dateien spielen (unkomprimiertes Audio oder Bitmaps), können Sie es mit --delta = dist = 2 versuchen (experimentieren Sie mit Wert, gute Werte sind 1..4).

Wenn Sie sehr abenteuerlustig sind, können Sie versuchen, mit mehr LZMA-Optionen zu spielen, wie z

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

(Dies sind die Standardeinstellungen. Sie können Werte zwischen 0 und 4 ausprobieren, und lc + lp dürfen 4 nicht überschreiten.)

Um zu sehen, wie die Standardvorgaben diesen Werten zugeordnet sind, können Sie die Quelldatei src / liblzma / lzma / lzma_encoder_presets.c überprüfen. Nichts von großem Interesse (-e setzt die schöne Länge auf 273 und passt auch die Tiefe an).

Anonym
quelle
6

Sie könnten verschiedene Optionen ausprobieren, für mich funktioniert -4e besser

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

Ich habe getestet mit:

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

Es scheint also, dass die Option -4e ein bisschen besser funktioniert als -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
quelle
3
Das beantwortet die Frage wirklich nicht. Dies ist nur eine Beobachtung, die besagt, dass -4e für Ihren speziellen kleinen Datensatz bereits die beste Komprimierung erhält und daher die höheren Ebenen keinen Vorteil mehr haben (und sogar eine noch so geringe Strafe).
Psusi
Sind Sie der gleiche Benutzer wie Szymon Roziewski ? Wenn ja, posten Sie bitte nicht mehrere Antworten. Bearbeiten Sie stattdessen Ihre ursprüngliche Antwort. Wenn Sie nicht auf Ihr erstes Konto zugreifen können, erfahren Sie hier, wie Sie Ihre Konten zusammenführen. In der Zwischenzeit lösche ich Ihre vorherige Antwort und füge sie hier ein.
Terdon
Ok, ich habe eine umfassendere Studie darüber durchgeführt. Was ich habe, ist hier. Ich habe einige Dateien von meiner Festplatte ausgewählt und die Komprimierung mit den Optionen -4e und -9e durchgeführt. Es ist also besser, die beste Lösung selbst zu finden. Sie hatten Recht, für einige Fälle -9e ist besser, während für andere nicht: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
(Kommentare können nur für 5 Minuten bearbeitet werden)txt 109 txt/pdf 135
Szymon Roziewski
2
+1. Dies hilft dem OP, eine Möglichkeit zu finden, die maximale Komprimierung für die tarVerwendung von Dateien zu bestimmen 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/    

auch mit externen Kompressoren komprimieren:

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

externe Kompressoren dekomprimieren:

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

Liste Archiv externe Kompressoren:

tar -I lz4 -tvf foo.tar.lz4
tar -I zstd -tvf foo.tar.zst
Goran Dragic
quelle
1
Dies scheint eine funktionierende Antwort zu sein, aber so wie es ist, würde es erheblich verbessert, wenn die Formatierung korrigiert und eine Erklärung der Option -Ihinzugefügt würde.
Dhag
4

tarBefehl verwendet JFlag für XZ-Dateien. Ein Beispiel:

tar -cJvf foo.tar.xz foo/

leonardoav
quelle
2
Das Jwurde bereits in bdownings Antwort erwähnt
Anthon
3

Für die Interessenten -e9ist 0,4% kleiner, 20% langsamer bei der Komprimierung, 3% langsamer bei der Dekomprimierung im Vergleich zu -9einem typischen Laptop. Das Timing wird in der Python-Quellcodeverzeichnisstruktur ausgeführt.

Kompression:

$ 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

Dekompression:

$ 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

Dateigröße:

$ 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
Kochfelder
quelle
1
Auswahl eines falschen Variablennamens, da T0 die Option zum Aktivieren der Multithread-Archivierung ist.
Dzenly
@ Dzenly Du hast recht! Danke! Änderte es.
Kochfelder
2

Dies ist keine exakte Antwort auf Ihre Frage, aber Sie können einen Befehl anstelle von zwei verwenden:

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

fügt alle Dateien aus dem Verzeichnis "dir1" mit "ultras ettings" zum Archiv archive.7z hinzu

Andere unterstützte Formate sind: zip, gzip, bzip2 oder tar. dafür einfach 7znach ersetzen -t.
--Quelleman 7z

HINWEIS: nicht verwenden Sie diesen Befehl zur Sicherung Ihrer Systemdateien außer persönlichen Dateien , weil das Format 7z nicht Dateisystem Berechtigungen speichern .

Edward Torvalds
quelle
5
Die Frage betraf xz und nicht 7z, obwohl beide LZMA-Komprimierung verwenden.
Amedee Van Gasse
2

Überprüfen Sie auf einem Multicore-Rechner ab Version 5.2.0 von xz-utils Folgendes:

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

Wenn Sie die maximale Anzahl von Kernen und die maximale Komprimierung verwenden möchten:

export XZ_DEFAULTS="-9 -T 0 "

Oder setzen Sie -T auf die Anzahl der Kerne, die Sie verwenden möchten.

Dann:

tar cJf target.tar.xz source

Dies kann auch nützlich sein, um die Komprimierungsstufe zu wählen:

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

Mirix
quelle
1

Wenn Sie möchten, dass dies schneller abgeschlossen wird, wenn Sie mehrere Threads verwenden, Ihr System jedoch nicht verlangsamen, während Sie andere Arbeiten ausführen, fügen Sie hinzu, -Tnwo n wie viele Threads verwendet werden sollen, niceund stufen Sie die Komprimierung auf Leerlaufpriorität herab.

Modell (für 4 Fäden):

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

Versuchen Sie es in topoder htopwenn Sie dies in einem großen Verzeichnis (mehrere GB) tun. Sie sollten hoffentlich mehrere xzThreads mit dem Nizza-Wert 19 (niedrigste Priorität) sehen.

Ich habe dies auch so knapp wie sinnvoll gestrippt, wie zum Beispiel: Die -f -in anderen Antworten wird einfach nicht benötigt, da tardie Standardausgabe stdout ist.

Sie können niceden Teer auch verarbeiten, aber ich habe es nie für notwendig befunden, da xzdie CPU für die Pipeline immer zu eng wird.

Praktische Anmerkung, ich benutze selten xz -9für irgendetwas, nicht so sehr wegen der CPU oder Zeit, sondern wegen des hohen Speicherbedarfs. Schauen Sie sich https://catchchallenger.first-world.info/wiki/Quick_Benchmark:_Gzip_vs_Bzip2_vs_LZMA_vs_XZ_vs_LZ4_vs_LZO#Memory_requirements_on_compression an . Der xzKompressor verwendet im bzip2Gegensatz dazu gzipmehr Speicher für höhere Kompressionsfaktoren. Zusammengenommen xzverbraucht dies weitaus mehr Speicher als jeder andere Kompressor. Sie können problemlos mehr als 600 MB Speicher verwenden. Wenn Sie die -TThread-Komprimierung aktivieren, steigen die Speicheranforderungen noch weiter. Beachten Sie Folgendes: Wenn Sie einen kleinen Dienst auf einer kleinen VM mit 1 bis 2 GB Arbeitsspeicher ausführen, kann dies versehentlich zu Beeinträchtigungen führen.

Joshua Huber
quelle
1

Unter Mac OS X besteht eine alternative tarMöglichkeit, den Parameter mit zu übergeben, darin, ein --options=Flag zu verwenden. Zum Beispiel,

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