tarアーカイブのパスを抽出せずに変換する


10

GNUにtar(1)はと呼ばれるきちんとしたオプションがあります--transform。manページから:

--transform、-xform EXPRESSION
は、sed replace EXPRESSIONを使用してファイル名を変換します

これにより、アーカイブの抽出中にその場でパス名を変換できるため、どこにどのように抽出するかを制御できます。

私の質問は、その場で同様の変換を実行する方法はありますか。つまり、アーカイブを抽出せずに?

[user@host]$ tar tf test.tar
./foo/blah  ./foo/bleh
[user@host]$ some_deep_magic 's/foo/bar/' test.tar
[user@host]$ tar tf test.tar
./bar/blah  ./bar/bleh

使用事例

tar基本的に無知なエンドユーザーにアーカイブを配布していますが、邪魔されずに正しいパスに抽出してほしいと思います。私は、アーカイブの抽出、ディレクトリの名前の変更、アーカイブが多すぎるので再パックするという簡単な解決策を避けようとしています。


作成時に名前を変換しないのはなぜですか?
マーティン

@JoseLuisMartinそうです。私のユースケースは、アーカイブがすでに存在していることです。前述したように、解凍、変換、再パックは避けたいと思います。
ジョセフR.

1
あなたは、実際にディスクにそれを抽出することなくタールの流れを変更することができます。github.com/mafintosh/tar-stream#modifying-existing-tarballsperldoc.perl.org/5.10.1/Archive/Tar.html、など
vladr

回答:


3

archivemountまたはmountavfsを使用してアーカイブをマウントし、再度作成することができます

archivemount tarfile.tar /mnt
cd /mnt
tar cf /tmp/tarfile.tar --transform 's/foo/bar/' .

アーカイブファイルシステムでの書き込み操作は、umountでの完全な再書き込みを実行するため、大きなファイルには適さないオプションです。

編集

実装の詳細はわかりませんが、書き込みファイルをファイルシステムに保存しているようです。

(私の/ usrのtarを超えて)男を解決するためにテストするだけです

#!/bin/bash

# try to avoid slab cache issues 
cat /tmp/usr.tar > /dev/null

T="$(date +%s)"
tar xf /tmp/usr.tar
tar cf usr.tar usr --transform 's/usr/foo/'
T="$(($(date +%s)-T))"
echo "Tar/Untar seconds: ${T}"

T="$(date +%s)"
archivemount -o readonly -o nobackup /tmp/usr.tar /mnt
tar cf usr.tar /mnt  --transform 's/usr/foo/'
umount /mnt
T="$(($(date +%s)-T))"
echo "Archivemount seconds: ${T}"

T="$(date +%s)"
mountavfs
cd '/root/.avfs/tmp/usr.tar#'
tar cf /tmp/test/usr.tar   --transform 's/usr/foo/' .
T="$(($(date +%s)-T))"
echo "Avfs seconds: ${T}"

出力:

Tar/Untar seconds: 480
Archivemount seconds:  failure, a lot of read errors.
Avfs seconds: 217

したがって、Avfsが勝利します。


1
+1興味深い新しいコマンド。しかし、このアプローチはアーカイブの解凍とどう違うのですか?私は実装についてではなく、パフォーマンスに関して話しています。
ジョセフR.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.