将tar文件解压后再压缩成tar文件的命令是什么?

8
我现在有一个tar.gz文件,我想从中提取一个或两个文件,并将它们打包/添加到一个新的tar.gz文件中,一次完成所有操作。当然,我可以将其保存到临时文件并进行操作,但是绝对要求是不产生任何中间文件输出,即使用管道。换句话说,我希望得到类似以下伪代码的内容(显然,语法是不正确的):
tar -xvf first.tar.gz subdir1/file1 subdir2/file2 | tar cf - | gzip > second.tar.gz

有谁知道这个的正确语法?我尝试了许多变量,但是都没有成功。

我也很乐意使用cpio的想法,但我不确定如何正确地编写语法,并且据我所知,cpio仅输入归档文件或文件名,而不是文件。

任何帮助都将不胜感激。

编辑:tarball中没有特定的文件名模式要提取。鉴于BSD和GNU tar只能一次搜索一个模式,我不确定是否可能使用包含/排除标志。


你要从第一个tarball中提取的文件名有一些模式吗? - fvwmer
我已经编辑了GNU tar和BSD tar的解决方案,以展示我的测试结果,两者都允许指定多个文件进行删除或包含。因此,这两个解决方案都适用于您的问题。 - Mark Adler
4个回答

5

我假设你正在使用或可以获取GNU tar

你可以使用--delete选项将一个tar文件处理到另一个tar文件中。例如:

% tar cf x.tar a b c d
% tar tf x.tar
a
b
c
d
% cat x.tar | tar f - --delete b c > y.tar
% tar tf y.tar
a
d
%

请注意,您可以指定多个名称进行删除。然后,您只需要弄清楚如何在命令行上指定要摆脱的所有文件,而不是要保留的文件。

这很不错,我建议再加一点。不要使用 y.tar,而是直接将其传输到下一个 tar 命令中。例如:cat x.tar | tar f - --delete b c | tar tf - - Trenton D. Adams
如果你想告诉tar要“保留”什么,那么你可以使用通配符模式来表示“删除除此之外的所有内容”,例如(保留除boot文件夹之外的所有内容):tar --wildcards --delete '*[^boot]' - Compholio

2
如果您知道要提取的文件名模式,请尝试以下操作:
tar zcf second.tar.gz --include='filepattern' @first.tar.gz

这里有一个例子,展示了如何包含多个文件:

% tar cf x.tar a b c d
% tar tf x.tar
a
b
c
d
% cat x.tar | tar cf - --include='a' --include='d' @- > y.tar
% tar tf y.tar
a
d
%

这也可以!但只适用于BSD tar。不幸的是,它不能用于GNU tar。因此,两者都有解决方案,但BSD tar提供了更接近所要求的解决方案。 - Mark Adler

1
没有上述解决方案适用于我,tar 抱怨创建了一个空档案。相反,我只是使用了 &&:
tar -xf first.tar.gz subdir1/file1 subdir2/file2 && tar -cvf second.tar --remove-files subdir1/file1 subdir2/file2 

--remove-files是在添加到归档文件后删除文件的选项。

我发现另一种可行的方法是:

tar -cf second.tar `tar -tf first.tar.gz /desired/directory`

请注意,它保持整个目录上下文,因此/desired/directory仍在新tar中。

0

在解压时,tar通常会将解压的文件写入磁盘而不是输出流。您可以使用-O或--to-stdout选项将文件写入标准输出,但文件之间没有分隔符,也无法知道一个文件何时结束另一个文件开始。

此外,tar的创建选项只能从磁盘读取文件,而不能从标准输入读取。这是有道理的,因为前面提到的问题是无法知道一个文件何时结束另一个文件开始。

这意味着没有办法按照您想要的方式从命令行执行此操作。

但是,我敢打赌,您可以编写一个Perl或Python脚本,使用可以严格在内存中操作的库。


如果需要在内存中操作,可以在shell中提取到RAM磁盘中。 - Barton Chittenden
可以使用GNU tar(无需RAM磁盘)。请参见我的答案。 - Mark Adler
而且使用BSD tar也是可能的(@fvwmer的回答)。当你说“没有办法做到这一点”时,请更加小心。 - Mark Adler
老旧的答案,我知道,但它确实帮了我。在这种情况下,问题标题与问题正文并不完全匹配。您回答了标题为“管道tar提取到tar创建”的部分,这正是我想知道的内容。其他答案涵盖了问题的真实用例,但那与我的不同。谢谢! - NotTheDr01ds

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接