Não deve ser muito difícil, pelo menos para arquivos compatíveis com o formato antigo, no qual os nomes de arquivos são armazenados em um campo de tamanho fixo (100 bytes), mas não conheço nenhuma ferramenta que pode renomear um arquivo no lugar em um arquivo tar. Além disso, com um arquivo compactado, você precisaria criar um novo arquivo de qualquer maneira.
Deve ser ainda mais fácil, mas eu não conheço nenhuma ferramenta existente que possa filtrar um arquivo, renomeando os arquivos como ele é. Você pode criar uma sobre bibliotecas de tar em linguagens de script; por exemplo, aqui está um script de prova de conceito para renomear um diretório em um arquivo tar usando Perl com Archive::Tar
. O arquivo é carregado inteiramente na memória; essa é uma limitação intrínseca de 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);
O GNU tar não tem a capacidade de renomear membros na hora, mas pax
(o substituto de POSIX para cpio
e tar
) faz. No entanto, você não pode fazer pax
ler e escrever em um arquivo. O que você pode fazer é expor o arquivo como uma árvore comum através do AVFS e criar um novo arquivo com pax
. Isso retém os nomes dos arquivos (exceto quando transformados), conteúdo, tempos e modos, mas redefine a propriedade do arquivo para você (a menos que seja executado como root).
mountavfs
cd "~/.avfs$PWD/old.tgz#"
pax -w -s '!bar!baz!' -s '!bar/!baz/' . | gzip >new.tgz