5

我现在有一个 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 一次只能搜索一种模式,我不确定是否可以分别使用包含/排除标志。

4

4 回答 4

4

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

您可以使用该--delete选项将一个 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
%

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

于 2012-07-13T02:50:27.730 回答
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
%
于 2012-07-13T03:18:37.537 回答
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 中。

于 2020-07-16T22:58:08.283 回答
0

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

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

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

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

于 2012-07-13T02:44:10.697 回答