Rename directory inside of a tar archive
It shouldn't be very difficult, at least for archives that are compatible with the old-style format where file names are stored in a fixed-size (100 bytes) field, but I don't know of any tool that can rename a file in place in a tar archive. Besides, with a compressed archive, you'd need to create a new file anyway.
It should be even easier, but I don't know of any existing tool that can filter an archive, renaming files as it goes. You can build one on top of tar libraries in scripting languages; for example, here's a proof-of-concept script to rename a directory in a tar archive using Perl with Archive::Tar
. The archive is loaded entirely into memory; this is an intrinsic limitation of 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 doesn't have the ability to rename members on the fly, but pax
(POSIX's replacement for cpio
and tar
) does. However, you can't make pax
both read and write from an archive. What you can do is expose the archive as a regular tree through AVFS, and create a new archive with pax
. This retains file names (except as transformed), contents, times and modes but resets file ownership to you (unless executed as root).
mountavfs
cd "~/.avfs$PWD/old.tgz#"
pax -w -s '!bar!baz!' -s '!bar/!baz/' . | gzip >new.tgz
Both sr_'s hack and Gilles' answer look very good, but if your problem is just the root directory name of the target tarball, while running rpmbuild, a different solution could be to re-define the %setup
macro to do the needed dir renaming.
Something like (you'll have to adapt and refine this to your actual configuration, in particular replacing old-dir
and desired-dir
and using the right decompression tool) this in your ~/.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 .
I wouldn't honestly do that if not in the most exotic situation, but yours could be the case :)
Just view this page but found the proper answer elsewhere:
http://www.rpm.org/max-rpm/s1-rpm-inside-macros.html
It says that you can pass -n to the %setup macro to tell rpmbuild the name of the top level folder within the tarball