关于linux:管道tar提取到tar创建

pipe tar extract into tar create

我现在有一个tar.gz,我只想从中提取一两个文件,然后将它们打包/添加到一个新的tar.gz中,一劳永逸。当然,我可以保存到一个临时文件并使用它,但绝对的要求是在没有任何中间文件输出(即管道)的情况下完成这一切。换句话说,我想要的是如下伪代码(显然语法不正确)

1
tar -xvf first.tar.gz subdir1/file1 subdir2/file2 | tar cf - | gzip > second.tar.gz

有人知道这个的正确语法吗?我试过很多变体,但都没有用。

我对使用cpio的想法也很开放,但同样地,我被如何正确地降低语法所困扰,据我所知,cpio只获取档案或文件名,而不是文件。

任何帮助都将不胜感激。

编辑:tarball中没有要提取的特定文件名模式。考虑到BSD和GNU tar一次只能搜索一个模式,我不确定是否可以分别使用include/exclude标志。


我假设您正在使用或可以获得GNU tar。

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

1
2
3
4
5
6
7
8
9
10
11
% 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
%

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


如果知道要提取的文件名模式,请尝试以下操作:

1
tar zcf second.tar.gz --include='filepattern' @first.tar.gz

下面是一个显示包含多个文件的示例:

1
2
3
4
5
6
7
8
9
10
11
% 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
%


在解包时,tar通常将解包的文件写入磁盘,而不是输出流。您可以使用-o或--to-stdout将文件写到stdout,但文件之间不会有中断,也不会有任何方法知道文件何时结束和另一个何时开始。

此外,tar的create选项只能从磁盘读取文件,而不能从stdin读取文件。这是有意义的,因为前面提到的知道一个文件何时结束和另一个文件何时开始的问题。

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

不过,我敢打赌,您可以使用库编写Perl或Python脚本,您可以在内存中严格地操作这些库。