重命名tar归档文件中的目录


14

是否可以在tar归档文件中重命名目录?我的用例是,我有一个外部提供的RPM规范文件,该文件假定一个具有特定目录结构的tarball,并且我有一个外部提供的tarball,其顶级目录名称与该规范文件所期望的名称不匹配。我既不控制生成tarball的脚本,也不控制RPM规范文件,因此我无法更改其中任何一个以匹配另一个。

我一直在做的事情是解压缩,更改目录名称,然后创建一个新的tarball,但是我想知道是否有替代方法。


3
不幸的是,我对此表示怀疑,但是我很想看看其他人是否有办法。我认为您最好的选择是编写一个脚本来解压缩,重命名和重新压缩。
凯文

Answers:


8

这应该不是很困难,至少对于与旧格式兼容的档案而言,文件名存储在固定大小(100字节)字段中,但是我不知道有什么工具可以重命名文件放在tar存档中。此外,对于压缩的存档,您仍然需要创建一个新文件。

它应该甚至更容易,但是我不知道任何现有的工具可以过滤存档,并在重命名文件时对其进行命名。您可以使用脚本语言在tar库的顶部构建一个库。例如,这是一个概念证明脚本,用于使用Perl和Archive::Tar来重命名tar归档文件中的目录。存档文件完全加载到内存中;这是的固有限制Archive::Tar

#!/usr/bin/env perl
## Usage: tar-rename OLDPREFIX NEWPREFIX
use strict;
use warnings;
use Archive::Tar;
my ($from, $to) = @ARGV;
my $tar = Archive::Tar->new(\*STDIN);
foreach my $file ($tar->get_files()) {
    my $name = $file->name;
    $name =~ s~\A\Q$from\E($|/)~$to$1~;
    $file->rename($name) unless $name eq $file->name;
}
$tar->write(\*STDOUT);

GNU tar无法即时重命名成员,但是pax(POSIX替代了cpiotar)可以。但是,您不能pax同时从存档中进行读取和写入。您可以做的是通过AVFS将档案公开为常规树,并使用创建新档案pax。这将保留文件名(转换后的文件名除外),内容,时间和模式,但会向您重置文件所有权(除非以root用户身份执行)。

mountavfs
cd "~/.avfs$PWD/old.tgz#"
pax -w -s '!bar!baz!' -s '!bar/!baz/' . | gzip >new.tgz

--transform从至少2010年开始,GNU Tar 就允许即时重命名文件。例如,请参阅:scriptsandoneliners.blogspot.com/2019/11/…–
A.Danischewski

@ A.Danischewski --transform允许您在构建或提取存档时重命名文件。但是,如何在不解压缩的情况下重命名存档中的文件呢?(提取不是一个好的解决方案:您可能没有足够的磁盘空间;您可能没有权限保留所有权信息;您可能没有能力完全保留时间戳记...)
Gilles'SO-别邪恶了'

好的,是的,我刚刚看到您的帖子指出“ GNU tar不能即时重命名成员”-确实可以,但是只能在进/出途中进行。如果要更改现有归档文件中的名称,则可以使用archivemount将其挂载到目录中,更改所需的名称,然后将其卸载。
A.Danischewski,

3

sr_的hack和Gilles的回答都很好,但是如果您的问题只是目标tarball的根目录名称,则在运行rpmbuild时,另一种解决方案是重新定义%setup宏以执行所需的目录重命名。

喜欢的东西(你必须去适应和完善这对你的实际配置,尤其是更换old-dirdesired-dir使用正确的解压工具)在此~/.rpmmacros

%setup cd ../BUILD \
rm -rf cd-player \
bunzip2 -dc ../SOURCES/%{name}-%{version}.tar.bz2 | tar -xvvf - \
if [ $? -ne 0 ]; then \
  exit $? \
fi \
mv <old-dir> <desired-dir> \
cd <desired-dir> \
cd ../BUILD/cd-player \
chmod -R a+rX,g-w,o-w .

如果不是在最奇特的情况下,我不会诚实地这样做,但是您的情况可能是这样的:)



1

丑陋的骇客,但也许对您tar有帮助,用符号链接愚弄:

$ mkdir a b
$ date >> b/foo
$ tar zcvf b-foo.tgz b/foo
$ rm -rf b
$ ln -s a b

$ tar zxvf b-foo.tgz                                                              
x b/foo: Cannot extract through symlink b
tar: Error exit delayed from previous errors.
$ tar zxvPf b-foo.tgz                                                             
x b/foo
$ ls a
foo

考虑一下,它可能不会,因为rpm不会让您弄乱的参数tar,会吗?(编辑:也许其中一些棘手的tar包装脚本$PATH可以解决这个问题。)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.