我有一个大文件foo.tar.xz
,其中包含很多(例如 200000 个)文件。我发现这个存档包含一些我不想要的文件(大约 5000 个)。我没有足够的磁盘空间将整个文件解压到我的磁盘上;此外,我担心如果我这样做,属性/权利可能会丢失。我有足够的空间来容纳两份副本压缩的不过存档。是否有工具可以即时从存档(在文件名上用正则表达式指定)中删除某些文件,即无需将存档解压成单独的文件?
答案1
GNU tar--delete
现在也有一个可以处理档案的选项。
像这样使用它,例如:
tar -vf yourArchive.tar --delete your/path/to/delete
谨防:很可能会不是适用于任何类型的磁带介质。但tar
在管道中工作没有问题,因此您只需使用临时 tar 文件,然后用该文件覆盖磁带即可。它也不适用于压缩文件,因此您需要解压缩文件。
此外,由于 tar 档案的(按设计)压缩线性性质,在任何情况下操作都会相当慢。
答案2
(编辑,因为我误解了这个问题,此后也进行了编辑)
您能做的最好的事情就是提取、删除并重新压缩整个文件。
unxz < foobar-old.tar.xz | tar --delete foo/bar | xz > foobar-new.tar.xz
无法直接从 tar 中删除文件。
tar 是一个流,最初用于不能很好地进行随机搜索的磁带驱动器 - 虽然理论上可以在磁盘文件系统上打一个洞/重写剩余的文件,但通过压缩,这一点是没有意义的,因为大多数(如果不是全部)压缩方法在很大程度上取决于文件中较早出现的内容。为了正确执行此操作,您需要非常详细地了解压缩方法以及 tar 文件格式。这太复杂了,以至于没有人会去理会它。只保留文件并忽略它们会更便宜。
如果您需要此功能,tar 可能不是您想要的。
答案3
正如其中所述投票最多的问题,GNU 焦油实现了一个--delete
似乎可以解决此问题的选项。
但引用诺莫夫评论:
注意:此命令可能会损坏您的 tar 文件。不幸的是,它毁了我的,而我又蠢到没有创建备份副本。我不确定原因是什么,但就我而言,它开始为每个文件创建数千个重复项。我必须对进程发出 SIGTERM,因为存档大小比原始大小增长了 10 倍,但此时数据已经丢失。
至少可以使用 tar 版本 v1.30 来重现,在版本 v1.34 中不会发生。它影响 armhf 和 i386 架构。
如果您尝试删除一个文件不存在在 tar 文件内,然后开始出现重复项,并且可能会发生整个文件的损坏。
如果tar
无法升级,解决方法是列出 tar 文件 ( --list
) 中的所有文件,并在尝试使用 删除之前检查文件是否存在--delete
。
答案4
根据手动的,您可以传递文件名列表以tar
仅提取这些文件名。例如:
$ tar --file archive.tar --list
foo
bar
baz
$ tar --file archive.tar --extract foo