Как сделать XZ каталог с TAR, используя максимальное сжатие?


116

Поэтому мне нужно сжать каталог с максимальным сжатием.

Как я могу это сделать xz? Я имею в виду, что мне тоже понадобится, tarпотому что я не могу сжать каталог только xz. Есть ли oneliner для производства, например 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 в нижнем регистре tar использует bzip, переключатель J в верхнем регистре использует xz.

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

Это сейчас максимально .

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

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

27
Нет, ты не В этом весь смысл. Вы можете установить переменную окружения только для этого вызова. Вы можете экспортировать его, если хотите, но не обязаны.
BSD

2
Для этого вы принимаете оболочку, похожую на bash.
anddam

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

1
Таким образом, чтобы установить оба параметра -9и -exz, вы хотите, XZ_OPT=-e9но, как указал @krzyk, -e очень медленно
hobs

4
Просто для записи: XZ_OPTэто не функция, реализованная в tar. Это особенность xz. Когда tarвызовы xz, окр-переменная просто передается.
Свен

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

даже лучше чем

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

5
Как это лучше? Что делает флаг e?
cxdf

2
option -e, --extremeИзмените предустановку сжатия (-0 ... -9) так, чтобы можно было добиться чуть лучшей степени сжатия без увеличения использования памяти компрессором или декомпрессором (исключение: использование памяти компрессора может немного увеличиться с предустановками -0 ... -2). Недостатком является то, что время сжатия резко возрастет (оно может легко удвоиться).
Эвандро-младший

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

1
xz по умолчанию использует 1 ядро ​​/ поток, вы можете максимально увеличить его (ускорить все это), добавив -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. Ничего особенного там нет (-e устанавливает красивую длину на 273, а также регулирует глубину).


6

Вы можете попробовать разные варианты, у меня -4е работает лучше

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 уже получает наилучшее сжатие, и поэтому более высокие уровни не получают больше выгоды (и даже очень незначительного штрафа).
Псуси

Вы тот же пользователь, что и Szymon Roziewski ? Если это так, пожалуйста, не размещайте несколько ответов. Вместо этого отредактируйте свой оригинальный ответ. Если вы не можете получить доступ к своей первой учетной записи, см. Здесь, как объединить свои учетные записи. А пока я удаляю ваш предыдущий ответ и включаю его здесь.
Тердон

Хорошо, я сделал более всестороннее исследование по этому вопросу. То, что я получил, здесь. Я выбрал некоторые файлы из моего жесткого диска и произвел сжатие с опциями -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
Шимон Розевский

(комментарии могут быть отредактированы только в течение 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уже упоминалось в ответе Бодинга
Anthon

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" в архив archive.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обрабатывать tar, но я никогда не считал это необходимым, так как xzвсегда узкие места в CPU для конвейера.

Практическое замечание, я редко использую 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многопоточное сжатие, требования к памяти возрастают еще больше. Просто что-то, о чем нужно знать, например, если вы работаете с небольшим сервисом на маленькой виртуальной машине с 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.