Ubah jalur arsip tar tanpa mengekstraksinya

10

GNU tar(1)memiliki opsi yang disebut rapi --transform. Dari halaman manual:

--transform, --xform EXPRESSION
gunakan dan ganti EXPRESSION untuk mengubah nama file

Ini memungkinkan transformasi nama jalur dengan cepat saat arsip diekstraksi sehingga Anda dapat mengontrol di mana dan bagaimana itu akan diekstraksi.

Pertanyaan saya adalah, adakah cara untuk melakukan transformasi serupa di situ ; yaitu, tanpa mengekstraksi arsip?

Contoh

[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

Gunakan kasing

Saya mendistribusikan tararsip pada dasarnya pengguna yang tidak mengerti dan ingin mengekstraknya ke jalur yang benar tanpa gangguan dari saya. Saya mencoba untuk menghindari solusi sepele dari mengekstraksi arsip, mengganti nama direktori dan mengemas ulang karena arsip lebih besar.

Joseph R.
sumber
Mengapa Anda tidak mengubah nama saat membuatnya?
Jose Luis Martin
@ JoseLuisMartin Benar. Kasus penggunaan saya adalah bahwa arsip sudah ada di sana dan, seperti yang saya katakan, saya ingin menghindari membongkar, mengubah dan mengemas ulang.
Joseph R.
1
Anda dapat memodifikasi aliran tar tanpa benar-benar penggalian itu ke disk: github.com/mafintosh/tar-stream#modifying-existing-tarballs , perldoc.perl.org/5.10.1/Archive/Tar.html , dll
vladr

Jawaban:

3

Anda bisa memasang arsip dengan archivemount atau mountavfs dan membuatnya kembali

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

operasi tulis pada sistem file arsip akan menampilkan penulisan ulang penuh pada umount, jadi sepertinya bukan pilihan yang baik untuk file besar.

EDIT

Saya tidak tahu detail implementasi tetapi sepertinya kami menyimpan file tulis ke langkah filesystem.

Cukup uji untuk menyelesaikan dudes, (di atas tar saya / usr)

#!/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}"

Keluaran:

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

Jadi Avf menang! .

Jose Luis Martin
sumber
1
+1 Perintah baru yang menarik. Tetapi bagaimana pendekatan ini berbeda dengan membongkar arsip? Saya tidak berbicara tentang implementasi, tetapi dari sisi kinerja.
Joseph R.