从巨大的 tgz 文件中提取单个文件

从巨大的 tgz 文件中提取单个文件

我有一个巨大的 tar 文件(大约 500G),我想从中提取单个文件。
但是,当我运行时,tar -xvf file.tgz path/to/file它似乎仍在将所有内容加载到内存中,并且需要一个多小时才能提取。我还尝试使用--exclude=ignore.txtignore.txt 是模式列表的位置来阻止它遍历无用路径,但这似乎不起作用。

也许我不理解 tar... 有没有办法可以快速提取文件?

答案1

不幸的是,为了解压.tar.gz档案中的单个成员,您必须处理整个档案,并且您无法采取太多措施来修复它。

这是.zip(和一些其他格式类似的.rar) 档案工作得更好的地方,因为zip格式具有包含在其中的所有文件的中心目录,其直接偏移量指向文件的中间zip,因此可以快速提取档案成员而无需处理整个内容。

您可能会问为什么处理.tar.gz这么慢?

.tar.gz(通常缩写为.tgz)只是.tar用压缩器压缩的存档gzipgzip是只能处理一个文件的流式压缩器。 如果您想获取gzip流的任何部分,您必须将其作为一个整体解压缩,而这才是真正让它失败的原因.tar.gz(以及.tar.bz2.tar.xz以及其他基于 的类似格式.tar)。

.tar格式实际上非常非常简单。它只是 512 字节文件或目录头(名称、大小等)的流,每个头后面跟着文件或目录内容(如果需要,用 0 字节填充到 512 块大小)。当您观察到头的 512 块完全为空时,这意味着.tar存档结束。

有些人认为甚至.tar无法快速访问存档成员,但事实并非如此相当确实如此。如果.tar档案包含少量大文件,您实际上可以快速搜索下一个标题,因此您可以在几次搜索中找到必要的档案成员(但仍然可能需要与档案成员数量一样多的搜索)。如果您的.tar档案包含大量小文件,这意味着即使对于未压缩的,快速成员检索实际上也变得不可能.tar

答案2

如果你只是从大型 tar 文件中提取一个文件,你正在使用 GNU tar并且你可以保证 tar 文件从未被附加到那么您可以通过使用获得显著的性能提升--occurrence

这个选项告诉 tar 在找到你请求的每个文件的第一次出现时立即停止,例如

tar xf large-backup.tar --occurrence etc/passwd etc/shadow

passwd在找到和的每个副本后,它将不会对整个 tarball 进行后台处理shadow,而是会停止。如果这些文件出现在末尾附近,性能提升不会很大,但如果它们出现在 500G 文件的中间,您将节省大量时间。

对于使用单次备份而不是使用真正的磁带驱动器的人来说,tar这种情况可能是典型的情况。

请注意,您还可以传递--occurrence=NUMBER以检索每个文件的第 NUMBERth 个出现,如果您知道存在档案中有多个版本。默认情况下,行为等于NUMBER1。

答案3

处理大型 tarball 时使用:

--fast-read仅提取与文件名操作数匹配的第一个存档条目,path/to/file在本例中,它在 tarball 中始终是唯一的

tar -xvf file.tgz --fast-read path/to/file

上述命令将搜索直到找到匹配项,然后退出

答案4

不幸的是,tar 文件格式不包含集中的目录 - 因此必须按顺序读取存档才能找到特定文件。它最初是为磁带备份而设计的(“tar”来自应收账无论如何,它都不支持这样的操作。

因此,您可能只需要等待。

相关内容