如何将许多压缩文件合并到一个存档中?


10

我有几百个.tar.xz几乎相同的文件(它们是每天的数据库转储,并且数据库更改缓慢)。

我相信,由于未压缩文件的相似性,它们将非常好地进行压缩,小规模测试表明,压缩任意数量的这些未压缩文件会创建一个仅比其中一个大的档案。

我的问题是所有未压缩的文件都将是几TB(压缩比约为25:1),而且我没有那么多的磁盘空间可以用作工作区。

有没有一种方法可以一次处理单个压缩文件,将它们添加到单个存档中,并保留将它们压缩在一起的好处?


您是否尝试过编写脚本,以便解压缩一个文件,然后将所有文件添加到给定的存档中,然后再移至下一个?
darnir 2014年

Answers:


10

由于tar文件是一种流格式-您可以cat将它们两个在一起并获得几乎正确的结果-您完全不需要将它们提取到磁盘即可。您可以(仅)解压缩文件,将它们串联在一起,然后重新压缩该流:

xzcat *.tar.xz | xz -c > combined.tar.xz

combined.tar.xz将是组件tarball中所有文件的压缩tarball,仅略有损坏。要提取数据,您必须使用(在GNU中)--ignore-zeros选项tar,因为存档确实有一个“文件结束”标记,该标记将出现在结果中间。除此之外,一切都将正常运行。

GNU tar还支持一种--concatenate用于产生组合档案的模式。这具有与上述相同的限制-您必须使用它--ignore-zeros来提取-但不适用于压缩档案。您可以构建一些东西来诱使它使用流程替换来工作,但这很麻烦,而且更加脆弱。

如果在不同的tar文件中有多次出现的文件,这将无法正常工作,但是无论如何您都会遇到这个问题。否则,这将为您提供所需的内容-通过管道传输输出xz始终是tar压缩输出的方式。


如果仅适用于特定tar实现的归档文件不足以满足您的目的,请与r您的朋友一起添加到归档文件中:

tar cJf combined.tar.xz dummy-file
for x in db-*.tar.xz
do
    mkdir tmp
    pushd tmp
    tar xJf "../$x"
    tar rJf ../combined.tar.xz .
    popd
    rm -r tmp
done

这一次只能提取一个存档,因此工作空间仅限于单个存档内容的大小。压缩就像流媒体一样,就像您一次完成最终存档一样,因此它会像以前一样出色。您将进行大量多余的解压缩和重新压缩,这将使它们比cat版本慢,但是生成的存档将在任何特殊支持下都可以工作。

请注意,根据您的实际需求,仅将未压缩的tar文件本身添加到存档中就足够了。它们将压缩(几乎)与其内容完全一样的单个文件,并且将减少每个文件的压缩开销。这看起来像:

tar cJf combined.tar.xz dummy-file
for x in db-*.tar.xz
do
    xz -dk "$x"
    tar rJf combined.tar.xz "${x%.xz}"
    rm -f "${x%.xz}"
done

就最终压缩的大小而言,这效率略低,因为流中有额外的tar标头,但在提取和重新添加所有文件作为文件时节省了一些时间。您最终将combined.tar.xz包含许多(未压缩的)db-*.tar文件。


谢谢,您的第二个选项很适合我的目的,但是您能否详细说明最后一段吗?看起来像什么?
2014年

@ jl6:请参见编辑。
迈克尔·荷马

抱歉,只能测试了一下。您的第二种方法给我这个错误:tar: Cannot update compressed archives
jl6 2014年
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.