Transformieren Sie die Pfade eines Teerarchivs, ohne sie zu extrahieren


10

GNU tar(1)hat eine nette Option namens --transform. Von der Manpage:

--transform, --xform EXPRESSION
Verwenden Sie sed replace EXPRESSION, um Dateinamen zu transformieren

Dies ermöglicht die Transformation von Pfadnamen im laufenden Betrieb, während das Archiv extrahiert wird, sodass Sie steuern können, wo und wie es extrahiert wird.

Meine Frage ist, gibt es eine Möglichkeit , eine ähnliche Transformation durchzuführen in situ ; dh ohne das Archiv zu extrahieren?

Beispiel

[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

Anwendungsfall

Ich verteile ein tarArchiv an grundsätzlich ahnungslose Endbenutzer und möchte, dass es ohne meine Einmischung in den richtigen Pfad extrahiert wird. Ich versuche, die triviale Lösung zu vermeiden, das Archiv zu extrahieren, die Verzeichnisse umzubenennen und neu zu packen, da das Archiv umfangreich ist.


Warum transformieren Sie beim Erstellen keine Namen?
Jose Luis Martin

@ JoseLuisMartin Richtig. Mein Anwendungsfall ist, dass das Archiv bereits vorhanden ist und ich, wie gesagt, das Auspacken, Transformieren und Umpacken vermeiden möchte.
Joseph R.

1
Sie können den Tar-Stream ändern, ohne ihn tatsächlich auf die Festplatte zu extrahieren: github.com/mafintosh/tar-stream#modifying-existing-tarballs , perldoc.perl.org/5.10.1/Archive/Tar.html usw.
vladr

Antworten:


3

Sie können das Archiv mit archivemount oder mountavfs mounten und erneut erstellen

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

Schreibvorgänge auf dem Archivdateisystem führen eine vollständige Umschreibung auf umount durch, daher scheint dies keine gute Option für große Dateien zu sein.

BEARBEITEN

Ich kenne keine Implementierungsdetails, aber es scheint, als würden wir die Schreibdateien im Dateisystemschritt speichern.

Testen Sie einfach, um Jungs zu lösen (über einen Teer von meinem / 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}"

Ausgabe:

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

Also gewinnt Avfs! .


1
+1 Interessanter neuer Befehl. Aber wie unterscheidet sich dieser Ansatz vom Auspacken des Archivs? Ich spreche nicht von der Implementierung, sondern von der Leistung.
Joseph R.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.