Як зробити XZ каталог з TAR, використовуючи максимальну компресію?


116

Тому мені потрібно стиснути каталог з максимальним стисненням.

Як я можу це зробити xz? Я маю на увазі, що мені це знадобиться, tarтому що я не можу стискати лише каталог xz. Чи є однолінійник для виробництва, наприклад foo.tar.xz?


11
FWIW, man 1 xzповідомляє 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 для отримання додаткової інформації.
cychoi

Відповіді:


82

Припускаючи, що xzвшановується стандартний набір прапорів командного рядка - включаючи прапорці рівня стиснення, ви можете спробувати:

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

і для цього використовується максимальний рівень стиснення з XZ?
LanceBaynes

3
додавання -9 до xz зробить це максимум
bsd

23
-9eнайкращий рівень, але це займе дуже довго
Кшиштоф Красонь

-9eне завжди дасть найкращий результат - див. пункт 8 тут rootusers.com/13-simple-xz-examples
KolonUK

1
Також ви можете побачити значне покращення, якщо додати --threads=0до xz
KolonUK

146

З останнім GNU tarна bash або похідній оболонці:

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

Для вимикача великої літери j використовується bzip, для верхнього регістру J перемикача використовується xz.

XZ_OPTЗмінна середовища дозволяє встановити xzпараметри , які не можуть бути передані з допомогою закликають додатків , таких як tar.

Це зараз максимально .

Перегляньте man xzінші параметри, які можна встановити ( -e/ --extreme може дати додаткову перевагу стиснення для деяких наборів даних).

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

27
Ні, ви цього не робите. У цьому вся суть. Ви можете встановити var середовища для саме цього виклику. Ви можете експортувати його, якщо хочете, але цього не потрібно.
bsd

2
Ви припускаєте, що для цього схожа оболонка.
anddam

7
@anddam, що підтримується всіми оболонками родини Борн (Bourne, ksh, mksh, pdksh, ash, dash, bash, yash, zsh) rcі akanga. fish, csh, tcshІ esбути основні снаряди , які не підтримують його. Там ви використовували б envкоманду.
Стефан Шазелас

1
Тож встановлювати обидві -9і -exz opts, ви хочете, XZ_OPT=-e9але як зазначав @krzyk, -e надзвичайно повільно
варити

4
Тільки для запису: XZ_OPTце не функція, реалізована в tar. Це особливість xz. Під час tarдзвінків xzзмінна env просто передається.
Свен

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

навіть краще, ніж

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

5
Як це краще? Що робить електронний прапор?
cxdf

2
option -e, --extremeЗмініть попередньо заданий рівень стиснення (-0 ... -9), щоб досягти трохи кращого коефіцієнта стиснення, не збільшуючи використання пам'яті компресора або декомпресора (виняток: використання пам'яті компресора може дещо збільшитися за допомогою попередньо встановлених налаштувань -0 ... -2). Мінусом є те, що час стиснення різко збільшиться (може легко подвоїтися).
Евандро-молодший

Отже, якщо я стискаю близько 80 Гб програмного забезпечення на своїй машині (коли я хочу, щоб усі ресурси комп’ютера перейшли до процесу стиснення на швидкість), я повинен використовувати -9не -9eтак, так?
nyxee

1
xz за замовчуванням використовує 1 core / thread, ви можете домогтися цього (прискорити все), додавши -T0, наприкладXZ_OPT="-9e -T0" tar -cJf ...
EkriirkE

10

Якщо у вас 16 Гб оперативної пам’яті (і більше нічого не працює), ви можете спробувати:

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

Для декомпресії знадобиться 1,5 Гб, а для стиснення - близько 11 разів. Відповідно відрегулюйте для меншої кількості пам'яті.

Це допоможе лише в тому випадку, якщо дані насправді такі великі, і в будь-якому випадку це НЕ допоможе ТАКІ багато, але все ж ...

Якщо ви стискаєте двійкові файли, додайте --x86 як перший варіант xz. Якщо ви граєте з "мультимедійними" файлами (нестиснене аудіо чи растрові зображення), ви можете спробувати --delta = dist = 2 (експериментуйте зі значенням, хороші значення для спробу - 1..4).

Якщо ви відчуваєте велику пригоду, можете спробувати пограти з іншими варіантами LZMA, наприклад

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

(це налаштування за замовчуванням. Ви можете спробувати значення від 0 до 4, а lc + lp не повинна перевищувати 4)

Для того, щоб побачити, як попередньо встановлені за замовчуванням відображають ці значення, ви можете перевірити вихідний файл src / liblzma / lzma / lzma_encoder_presets.c. Нічого особливого цікавого там немає (-е встановлює хорошу довжину в 273, а також регулює глибину).


6

Ви можете спробувати різні варіанти, для мене -4e працює краще

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

Я перевірив:

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

Отже, здається, що варіант -4e працює трохи краще, ніж -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
Це справді не відповідає на питання. Це лише спостереження, що для вашого конкретного невеликого набору даних -4e вже отримує найкращу компресію, і тому більш високі рівні не отримують більше користі (і навіть настільки незначного штрафу).
psusi

Ви такий самий користувач, як Szymon Roziewski ? Якщо так, будь ласка, не публікуйте декількох відповідей. Натомість відредагуйте оригінальну відповідь. Якщо ви не можете отримати доступ до свого першого облікового запису, перегляньте тут, як об’єднати свої акаунти. Тим часом я видаляю вашу попередню відповідь і включаю її сюди.
terdon

Гаразд, я провів більш всебічне дослідження з цього питання. Що я тут маю. Я вибрав кілька файлів з мого жорсткого диска і зробив компресію з опціями -4e та -9e. Отже, краще знайти найкраще рішення самостійно. Ви мали рацію, для деяких випадків краще -9e, тоді як для інших це не так: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

(коментарі можна редагувати лише протягом 5 хвилин)txt 109 txt/pdf 135
Szymon Roziewski

2
+1. Це допомагає ОП знайти спосіб визначення максимальної компресії для tarфайлів за допомогою файлів 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/    

також стискають із зовнішніми компресорами:

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

декомпресувати зовнішні компресори:

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

список архівів зовнішніх компресорів:

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

1
Це здається робочою відповіддю, але, як це є, це було б значно покращено, встановивши його форматування та пояснення опції -I.
даг

4

tarкоманда використовує Jпрапор для файлів xz. Приклад:

tar -cJvf foo.tar.xz foo/


2
Про Jце вже згадувалося у відповіді на викривлення
Антон

3

Для тих, хто цікавиться, -e9на 0,4% менше, на 20% повільніше при стисненні, на 3% повільніше для декомпресії, порівняно -9з типовим ноутбуком. Ось час працює в структурі каталогів вихідного коду Python.

Стиснення:

$ 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

Декомпресія:

$ 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

Розмір файлу:

$ 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
Неправильний вибір імені змінної, оскільки T0 - це можливість ввімкнути багатопотокове архівування.
Дзенлі

@Dzenly Ти маєш рацію! Дякую! Змінив це.
варильні панелі

2

Це не точна відповідь на ваше запитання, але ви можете використовувати одну команду замість двох:

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

додає всі файли з каталогу "dir1" в архів архіву.7z, використовуючи "ultras ettings"

інші формати, що підтримуються: zip, gzip, bzip2 або tar. для цього просто замініть 7zпісля -t.
- джерелоman 7z

ПРИМІТКА: не використовуйте цю команду для резервного копіювання системних файлів, крім особистих файлів, оскільки формат 7z не зберігає дозволи файлової системи .


5
Питання стосувалося xz, а не 7z, хоча вони обидва використовують стиснення LZMA.
Амедей Ван Гассе

2

У багатоядерній машині з версії v5.2.0 xz-utils перевірте:

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

Якщо ви хочете використовувати максимальну кількість ядер і максимальну компресію:

export XZ_DEFAULTS="-9 -T 0 "

Або встановіть -T на кількість ядер, які ви хочете використовувати.

Тоді:

tar cJf target.tar.xz source

Також це може бути корисно для вибору рівня стиснення:

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


1

Якщо ви хочете, щоб це завершилося швидше, використовуючи декілька потоків, але не сповільнюючи систему під час виконання іншої роботи, спробуйте додати, -Tnде n - скільки потоків, які ви хочете використовувати, а також niceзменшити компресію на пріоритет простою.

Модель (для 4-х ниток):

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

Спробуйте переглядати topабо htopколи ви робите це у великому каталозі (кілька ГБ). Сподіваємось, ви побачите кілька xzпотоків із значенням Nice 19 (найнижчий пріоритет).

Я також позбавив цього, настільки ж стислий, наскільки розумний, як-от: -f -інші відповіді просто не потрібні, оскільки tarвихід за замовчуванням - stdout.

Можна niceтакож обробляти смолу, але я ніколи не вважав це необхідним, як xzзавжди вузькі місця процесора для конвеєра.

Практична примітка, я рідко використовую xz -9ні для чого, не стільки через процесор чи час, скільки через високі потреби в пам'яті. Погляньте на https://catchchallenger.first-world.info/wiki/Quick_Benchmark:_Gzip_vs_Bzip2_vs_LZMA_vs_XZ_vs_LZ4_vs_LZO#Memory_requirements_on_compression . xzКомпресора, як bzip2, але , в відміну gzip, використовує більше пам'яті для більш високих коефіцієнтів стиску. Крім того, що разом з цим xzвикористовується набагато більше пам’яті, ніж будь-який інший компресор, ви можете легко використовувати до 600 Мб пам'яті. І якщо ви використовуєте -Tдля ввімкнення потокового стиснення, вимоги до пам'яті збільшуються ще більше. Просто щось, про що слід пам’ятати, наприклад, якщо ви користуєтеся невеликим сервісом на невеликому VM з 1-2 ГБ пам’яті, ви можете ненавмисно спричинити вплив.


1

У Mac OS X альтернативний підхід для передачі параметра з tarвикористанням полягає у використанні --options=прапора. Наприклад,

tar Jcvf targetFileName.tar.xz --options='compression-level=9' directoryName
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.