tarアーカイブ内のディレクトリ名を変更します


14

tarアーカイブ内のディレクトリの名前を変更することは可能ですか?私のユースケースは、特定のディレクトリ構造を持つtarballを想定した外部から提供されたRPMスペックファイルがあり、トップレベルのディレクトリ名がスペックファイルが期待するものと一致しない外部から提供されたtarballがあることです。私はtarballを生成するスクリプトもRPM仕様ファイルも制御しないので、どちらか一方に変更を加えて他方に一致させることはできません。

私がやっているのは、tarを解除し、ディレクトリ名を変更してから、新しいtarballを作成することです。


3
残念ながら、私はそれを疑いますが、他の誰かが道を持っているかどうかを確認したいと思います。最善の策は、untar、rename、およびre-tarするスクリプトを書くことだと思います。
ケビン

回答:


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のcpioand の代替tar)にはあります。ただし、paxアーカイブから読み取りと書き込みの両方を行うことはできません。あなたができることはAVFSを通してアーカイブを通常のツリーとして公開して、で新しいアーカイブを作成することですpax。これにより、ファイル名(変換されたものを除く)、内容、時間、モードは保持されますが、ファイルの所有権は(rootとして実行されない限り)リセットされます。

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

GNU Tarは--transform少なくとも2010年以来、その場でファイル名を変更することができました。例については、scriptsandoneliners.blogspot.com
2019/11

@ A.Danischewskiを--transform使用すると、アーカイブを構築または抽出するときにファイルの名前を変更できます。しかし、アーカイブ内のファイルの名前を抽出せずに変更するにどうすればよいですか?(抽出は良い解決策ではありません。十分なディスク容量がない場合があります。所有権情報を保持する権限がない場合があります。タイムスタンプを正確に保持することができない場合があります。)
Gilles

さて、あなたの投稿で「GNU tarはその場でメンバーの名前を変更することはできません」と言っています。既存のアーカイブ内の名前を変更する場合は、archivemountを使用してディレクトリにマウントし、必要な名前を変更してアンマウントできます。
A.ダニシェウスキ

3

sr_のハックと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

Uいハックですが、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これを回避できます。)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.