如何使用最大压缩率使用TAR对目录进行XZ处理?


115

因此,我需要使用最大压缩率来压缩目录。

我该怎么办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 2015年

Answers:


82

假设xz遵循标准的命令行标志集-包括压缩级别标志,则可以尝试:

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

并使用XZ的最大压缩级别?
LanceBaynes

3
加入-9 XZ将使其最大
BSD

23
-9e是最好的级别,但是需要很长时间
KrzysztofKrasoń16年

-9e不会总是给您最好的结果-在此处查看第8点rootusers.com/13-simple-xz-examples
KolonUK

1
另外,如果您添加--threads=0到xz ,则可能会看到明显的改进
KolonUK

145

tar在bash或派生的shell上使用最新的GNU :

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

tar的小写j开关使用bzip,大写J开关使用xz。

XZ_OPT环境变量可以设置xz无法通过调用应用程序,如传递选项tar

现在这是最大的

请参阅man xz以了解其他可以设置的选项(-e/ --extreme 可能会为您提供某些数据集的其他压缩优势)。

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

27
不,你没有。这就是重点。您可以只为该调用设置环境var。如果需要,可以将其导出,但不必这样做。
2013年

2
您为此假设bash-like shell。
anddam

7
@anddam,这是Bourne家族的所有shell(Bourne,ksh,mksh,pdksh,ash,dash,bash,yash,zsh)和rcand支持的akangafishcshtcsh并且es是不支持它主要的炮弹。在那里,您将使用env命令。
斯特凡Chazelas

1
因此,要同时设置-9-exz opts,都需要,XZ_OPT=-e9但是正如@krzyk指出的那样,-e 极其
滚刀

4
仅作记录:XZ_OPT不是在中实现的功能tar。这是的功能xz。当tar调用时xz,env变量被简单地传递。
Sven

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)。缺点是压缩时间会急剧增加(很容易翻倍)。
Evandro Jr

因此,如果我要在计算机上压缩大约80GB的软件(当我希望所有计算机资源都进入压缩过程以提高速度时),我应该不使用-9-9e,是吗?
nyxee

1
默认情况下,xz使用1个核心/线程,您可以通过添加-T0来最大程度地提高(加速),例如XZ_OPT="-9e -T0" tar -cJf ...
EkriirkE

10

如果您有16 GiB的RAM(并且没有其他任何运行),则可以尝试:

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

解压缩将需要1.5 GiB,而压缩则需要约11倍。相应地调整以减少内存量。

如果数据实际上是很大的,这只会帮助,在任何情况下它不会帮助THAT多,但仍...

如果要压缩二进制文件,请添加--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

您可能会尝试其他选项,对我来说-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 2015年

您与Szymon Roziewski是同一用户吗?如果是这样,请不要发布多个答案。而是编辑原始答案。如果您无法访问您的第一个帐户,请参阅此处以了解如何合并您的帐户。同时,我正在删除您以前的答案,并将其包括在此处。
terdon

好的,我对此进行了更全面的研究。我得到的是这里。我从hardrive中选择了一些文件,并使用选项-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 2015年

(评论只能编辑5分钟)txt 109 txt/pdf 135
Szymon Roziewski 2015年

2
+1。这不利于OP找到一种方法来确定最大压缩tar使用荷兰国际集团的文件xz
cychoi 2015年

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添加选项说明,可以极大地改善它。
dhag


3

-e9-9普通笔记本电脑相比,对于感兴趣的用户来说,体积要小0.4%,压缩时要慢20%,减压时要慢3%。这是在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

@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压缩。
阿米德·范·加斯


1

如果您希望使用多个线程来完成此任务更快,但又不减慢系统执行其他工作时的速度,请尝试添加-Tnn是要使用的线程数,nice并将压缩降级为空闲优先级。

型号(4个线程):

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

尝试在大型目录(几个GB)中tophtop在其中观看时。您应该希望看到几个xz线程的Nice值为19(最低优先级)。

我也将其简化为明智的,例如:-f -根本不需要其他答案,因为tar默认输出为stdout。

您也可以nice使用tar进程,但是我从来没有发现它是必需的,因为它xz总是阻塞CPU的流水线。

切记,我很少使用xz -9任何东西,不是因为CPU或时间而花太多钱,而是因为内存需求高。看看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+ MB的内存。而且,如果使用-T启用线程压缩,则内存需求会进一步上升。只是要注意一点,例如,如果您在具有1-2 GB内存的小型VM上运行一些小型服务,则可能会无意中造成影响。


1

在Mac OS X上,传递参数with的另一种方法tar是使用--options=标志。例如,

tar Jcvf targetFileName.tar.xz --options='compression-level=9' directoryName
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.