Jak XZ katalogu z TAR przy użyciu maksymalnej kompresji?


116

Więc muszę skompresować katalog z maksymalną kompresją.

Jak mogę to zrobić xz? To znaczy, będę tarteż potrzebować, ponieważ nie mogę skompresować katalogu tylko xz. Czy istnieje oneliner do produkcji np. foo.tar.xz?


11
FWIW, man 1 xzmówi 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, aby uzyskać więcej informacji.
szczegółowooi

Odpowiedzi:


82

Zakładając, że xzhonoruje standardowy zestaw flag wiersza poleceń - w tym flag poziomu kompresji, możesz spróbować:

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

a to wykorzystuje maksymalny poziom kompresji w XZ?
LanceBaynes

3
dodanie -9 do xz spowoduje, że będzie to maksimum
bsd

23
-9eto najlepszy poziom, ale potrwa to bardzo długo
Krzysztof Krasoń,

-9enie zawsze da ci najlepszy wynik - patrz punkt 8 tutaj rootusers.com/13-simple-xz-examples
KolonUK

1
Ponadto możesz zauważyć znaczną poprawę, jeśli dodasz --threads=0do xz
KolonUK

146

Z najnowszym GNU tarw bash lub pochodnej powłoce:

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

Przełącznik j małych znaków tar używa bzip, przełącznik J wielkich liter używa xz.

XZ_OPTZmienna pozwala ustawić xzopcje, które nie mogą być przekazywane za pośrednictwem aplikacji, takich jak zawijających tar.

To jest teraz maksymalne .

Sprawdź man xzinne opcje, które możesz ustawić ( -e/ --extreme może dać ci dodatkowe korzyści kompresji dla niektórych zestawów danych).

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

27
Nie, ty nie. To o to chodzi. Możesz ustawić zmienne środowiskowe tylko dla tego wywołania. Możesz go wyeksportować, jeśli chcesz, ale nie musisz.
bsd

2
Zakładasz do tego powłokę przypominającą bash.
anddam

7
@anddam, który jest obsługiwany przez wszystkie powłoki rodziny Bourne (Bourne, ksh, mksh, pdksh, ash, dash, bash, yash, zsh) rci akanga. fish, csh, tcshI esjest głównym muszle, które nie obsługują. Tam użyjesz envpolecenia.
Stéphane Chazelas,

1
Więc żeby ustawić oba -9i -exz, chcesz, XZ_OPT=-e9ale jak zauważył @krzyk, -e jest bardzo wolny
płyty

4
Dla przypomnienia: XZ_OPTnie jest funkcją zaimplementowaną w tar. Jest to cecha xz. Podczas tarwywoływania xzzmienna env jest po prostu przekazywana.
Sven

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

jest nawet lepszy niż

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

5
Jak to jest lepsze? Do czego służy flaga e?
cxdf,

2
option -e, --extremeZmodyfikuj ustawienie kompresji (-0 ... -9), aby uzyskać nieco lepszy współczynnik kompresji bez zwiększania zużycia pamięci przez kompresor lub dekompresor (wyjątek: użycie pamięci kompresora może nieznacznie wzrosnąć przy ustawieniach -0 ... -2). Minusem jest to, że czas kompresji dramatycznie wzrośnie (można go łatwo podwoić).
Evandro Jr

Tak więc, jeśli kompresuję około 80 GB oprogramowania na moim komputerze (kiedy chcę, aby wszystkie zasoby komputerów przeszły do ​​procesu kompresji dla szybkości) , -9nie powinienem używać -9e, tak?
nyxee

1
xz domyślnie używa 1 rdzeń / wątek, możesz to maksymalnie zwiększyć (przyspieszyć to wszystko), dodając -T0, np.XZ_OPT="-9e -T0" tar -cJf ...
EkriirkE

10

Jeśli masz 16 GiB RAM (i nic więcej nie działa), możesz spróbować:

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

Będzie to wymagało 1,5 GiB do dekompresji i około 11 razy więcej do kompresji. Dostosuj odpowiednio dla mniejszej ilości pamięci.

Pomoże to tylko wtedy, gdy dane są w rzeczywistości tak duże, a w każdym razie nie pomoże TEGO dużo, ale nadal ...

Jeśli kompresujesz pliki binarne, dodaj --x86 jako pierwszą opcję xz. Jeśli grasz z plikami „multimedialnymi” (nieskompresowane audio lub mapy bitowe), możesz spróbować z --delta = dist = 2 (eksperymentuj z wartością, dobre wartości to 1..4).

Jeśli czujesz się bardzo ryzykowny, możesz spróbować grać z większą liczbą opcji LZMA, takich jak

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

(są to ustawienia domyślne, możesz wypróbować wartości od 0 do 4, a lc + lp nie może przekraczać 4)

Aby zobaczyć, w jaki sposób domyślne ustawienia wstępne mapują się na te wartości, możesz sprawdzić plik źródłowy src / liblzma / lzma / lzma_encoder_presets.c. Nie ma tam jednak większego zainteresowania (-e ustawia ładną długość na 273, a także dostosowuje głębokość).


6

Możesz wypróbować różne opcje, dla mnie -4e działa lepiej

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

Testowałem, uruchamiając:

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

Wygląda więc na to, że opcja -4e działa nieco lepiej niż -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
To naprawdę nie odpowiada na pytanie. Jest to tylko spostrzeżenie, że dla twojego konkretnego małego zestawu danych, -4e ma już najlepszą kompresję, więc wyższe poziomy nie zyskują więcej korzyści (a nawet bardzo niewielkiej kary).
psusi

Czy jesteś tym samym użytkownikiem, co Szymon Roziewski ? Jeśli tak, nie publikuj wielu odpowiedzi. Zamiast tego edytuj swoją oryginalną odpowiedź. Jeśli nie możesz uzyskać dostępu do pierwszego konta, zobacz tutaj, jak połączyć swoje konta. W międzyczasie usuwam twoją poprzednią odpowiedź i zamieszczam ją tutaj.
terdon

Ok, przeprowadziłem bardziej wszechstronne badanie tego. Mam tutaj. Wybrałem niektóre pliki z dysku twardego i dokonałem kompresji za pomocą opcji -4e i -9e. Lepiej więc samemu znaleźć najlepsze rozwiązanie. Miałeś rację, w niektórych przypadkach -9e jest lepszy, podczas gdy w innym nie jest: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,

(komentarze można edytować tylko przez 5 minut)txt 109 txt/pdf 135
Szymon Roziewski

2
+1. Pomaga to OP znaleźć sposób na określenie maksymalnej kompresji przy tarużyciu plików xz.
szczegółowooi

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/    

również kompresuj za pomocą zewnętrznych sprężarek:

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

zdekompresować zewnętrzne sprężarki:

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

lista archiwum kompresory zewnętrzne:

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

1
Wydaje się to działającą odpowiedzią, ale w obecnej sytuacji zostałby znacznie ulepszony poprzez poprawienie formatowania i -Idodanie wyjaśnienia opcji .
dhag

4

tarpolecenie używa Jflagi dla plików xz. Przykład:

tar -cJvf foo.tar.xz foo/


2
JJuż wspomniano w odpowiedzi bdowning za
Anthon

3

Dla zainteresowanych -e9jest o 0,4% mniejszy, 20% wolniejszy przy kompresji, 3% wolniejszy przy dekompresji, w porównaniu do -9typowego laptopa. Oto przebiegi czasowe w strukturze katalogów kodu źródłowego Pythona.

Kompresja:

$ 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

Dekompresja:

$ 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

Rozmiar pliku:

$ 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
Wybór niepoprawnej nazwy zmiennej, ponieważ T0 jest opcją włączenia archiwizacji wielowątkowej.
Dzenly,

@Dzenly Masz rację! Dziękuję Ci! Zmieniłem to.
płyty grzewcze

2

To nie jest dokładna odpowiedź na twoje pytanie, ale możesz użyć jednego polecenia zamiast dwóch:

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

dodaje wszystkie pliki z katalogu „dir1” do archiwum archive.7z przy użyciu „ultras ettings”

inne obsługiwane formaty to: zip, gzip, bzip2 lub tar. w tym celu wystarczy wymienić 7zpo -t.
--źródłoman 7z

UWAGA: nie używaj tego polecenia do tworzenia kopii zapasowych plików systemowych oprócz plików osobistych, ponieważ format 7z nie przechowuje uprawnień systemu plików .


5
Pytanie dotyczyło xz, a nie 7z, mimo że oba używają kompresji LZMA.
Amedee Van Gasse,

2

Na maszynie wielordzeniowej od wersji v5.2.0 xz-utils sprawdź:

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

Jeśli chcesz użyć maksymalnej liczby rdzeni i maksymalnej kompresji:

export XZ_DEFAULTS="-9 -T 0 "

Lub ustaw -T na liczbę rdzeni, których chcesz użyć.

Następnie:

tar cJf target.tar.xz source

Może to również być przydatne do wyboru poziomu kompresji:

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


1

Jeśli chcesz, aby zakończyło się to szybciej, używając wielu wątków, ale bez spowalniania systemu podczas wykonywania innej pracy, spróbuj dodać -Tngdzie n oznacza liczbę wątków, których chcesz użyć, a także niceobniżyć kompresję do priorytetu bezczynności.

Model (dla 4 wątków):

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

Spróbuj obejrzeć toplub htopkiedy zrobisz to w dużym katalogu (kilka GB). Mamy nadzieję, że powinieneś zobaczyć kilka xzwątków o wartości Nicei 19 (najniższy priorytet).

Rozebrałem to również tak zwięźle, jak rozsądnie, na przykład: -f -inne odpowiedzi nie są po prostu potrzebne, ponieważ tardomyślnym wyjściem jest standardowe wyjście.

Możesz nicerównież przetwarzać tar, ale nigdy nie uważałem tego za konieczne, ponieważ xzzawsze wąskie gardło procesora dla potoku.

Praktyczna uwaga: rzadko używam xz -9do niczego, nie tyle ze względu na procesor lub czas, ale z powodu wysokich wymagań pamięci. Spójrz na https://catchchallenger.first-world.info/wiki/Quick_Benchmark:_Gzip_vs_Bzip2_vs_LZMA_vs_XZ_vs_LZ4_vs_LZO#Memory_requirements_on_compression . xzKompresor, jak bzip2, ale w przeciwieństwie do gzip, wykorzystuje więcej pamięci dla wyższych współczynników kompresji. Łącznie z tym, że xzzużywa znacznie więcej pamięci niż jakikolwiek inny kompresor, możesz z łatwością zużyć ponad 600 MB pamięci. A jeśli używasz tej opcji, -Taby włączyć kompresję wątkową, wymagania dotyczące pamięci idą jeszcze dalej. Tylko coś, o czym należy pamiętać, na przykład jeśli prowadzisz małą usługę na małej maszynie wirtualnej z pamięcią 1-2 GB, możesz przypadkowo spowodować wpływ.


1

W systemie Mac OS X alternatywnym podejściem do przekazania parametru z tarjest użycie --options=flagi. Na przykład,

tar Jcvf targetFileName.tar.xz --options='compression-level=9' directoryName
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.