Zeigen Sie eine Datei in einem Teerarchiv an, ohne sie zu extrahieren

16

Ich möchte den Inhalt der geteerten Datei anzeigen, ohne ihn zu extrahieren. Szenario: Ich habe a.tar und darin befindet sich eine Datei namens ./x/y.txt. Ich möchte den Inhalt von anzeigen, y.txtohne das tatsächlich zu extrahieren a.tar.

Ramji
quelle
Wenn Sie Emacs verwenden, können Sie einfach den Tarball darin öffnen.
Qudit
Ähm, um es anzuzeigen, müssen Sie es extrahieren. Ich denke, was Sie meinen, ist "ohne es in eine Datei zu schreiben"?
Toby Speight

Antworten:

20

Es ist wahrscheinlich eine GNU-spezifische Option, aber Sie können das -Ooder verwenden --to-stdout, um Dateien in die Standardausgabe zu extrahieren

$ tar -axf file.tgz foo/bar -O
Fredtantini
quelle
Ah funktioniert, aber ich habe es nicht geschafft, die Ausgabe in neuen Zeilen zu drucken. Ex; tar -axf file.tar.gz --wildcards --no-anchored '*read_this_file*' --Owenn zum Beispiel viele Dateien übereinstimmen *read_this_file*. Alles wird in derselben Zeile gedruckt. Aus dem habe manich gefunden --to-command. Passing --to-command="echo '' && cat"ist ein bisschen schwarze Magie, aber es funktioniert: D
GabLeRoux
Genau dies wird als Antwort benötigt:$ tar -axf file.tgz foo/bar -O
user1742529
12

Dies druckt den Inhalt von ./x/y.txt von a.tar nach STDOUT.

tar xfO a.tar ./x/y.txt

Toni
quelle
2
Hinweis: Es ist ein Großbuchstaben "o", nicht Null.
Hubert Grzeskowiak
4

Das ist so einfach wie

less  a.tar:./x/y.txt

Dieser Zaubertrick funktioniert, wenn Sie lesspipeinstalliert haben und wenn die env-Variable LESSOPENals definiert definiert ist, | /usr/bin/lesspipe.sh %swas erwartet wird, wenn Sie lesspipe korrekt installiert haben.

Sonnenwende
quelle
Das ist ein großartiges Skript - aber es gibt mehr als eines. Wie ich es verstehe, dieslesspipe.sh sollte wohl vorzuziehen.
Mikeserv
Funktioniert das bei komprimierten Tarballs?
Terdon
Es sollte. Aber ich habe gerade festgestellt, dass es in Ubuntu nicht funktioniert. Stelle dir das vor. Sie haben die Funktion beschädigt oder entfernt. Sie können immer noch Archivliste mit weniger, aber nicht Dateiinhalt anzeigen :-(
solsTiCe
2

Oh, aber dies ist eine Frage zum Inhalt einer Datei innerhalb einer tarDatei. Und tatsächlich ist dies in einigen Fällen nicht so schwer. Die Sache ist, eine tarDatei ist nur eine blockierte Stream-Datei - jede Datei im Archiv wird nach der vorhergehenden gefunden, und jede Datei erhält einen Metadaten- Header, der auf einem bestimmten Format basiert .

Basierend auf diesem Format habe ich einmal geschrieben shitar- das waren ein paar Zeilen ddund Shell-Skripte, die tareinen Strom von Blockgeräten im laufenden Betrieb aufbauen konnten . Basierend darauf habe ich in jüngerer Zeit diese wenigen Codezeilen geschrieben :

tar --no-recursion -c ./      |
{ printf \\0; tr -s \\0; }    |
cut -d '' -f-2,13             |
tr '\0\n' '\n\t'

... um eine tarDatei im laufenden Betrieb auseinanderzunehmen und Inline-Transformationen für ihre Komponententextdateien durchzuführen. Dort werden die cutFelder verweisen auf Felder 1,2,13 einer NUL abgegrenzte Linie von Eingabe. Solche Dinge sind einfach, wenn die tarDatei nur Textdateien enthält, da tardie Datensatztrennzeichen (wie sie alle 512 Bytes auftreten können) nur auf eine einzelne NUL pro Person reduziert und entfernt werden können - ohne dass Sie die Vorkommen wie gewohnt zählen müssen.

tarDas Header-Format sieht folgendermaßen aus:

field    offset   len
name     0        100
mode     100      8
uid      108      8
gid      116      8
size     124      12
mtime    136      12
chksum   148      8
typeflag 156      1
linkname 157      100
magic    257      6
version  263      2
uname    265      32
gname    297      32
devmajor 329      8
devminor 337      8
prefix   345      155

Verstehen Sie, dass es einen steilen Hang zwischen der relativ einfachen Handhabung einfach gibt tar Vorgänge und den weitaus komplizierteren Aspekten des Archivformats . Während einfache Dinge - wie das Zusammenpacken einer kleinen Gruppe homogen typisierter Dateien oder sogar das Aufteilen eines Archivs, das nur Mitglieder enthält, deren Typen Sie vorhersagen können - mit wenigen Shell-Pipes problemlos erledigt werden können, ist der zuverlässige Umgang mit beliebigen Archivmitgliedern keine Kleinigkeit.

Es ist besonders schwierig, wenn diese Mitglieder beliebige Binärdaten enthalten könnten - was sicherlich eine zuverlässige Anwendung von ausschließen würde tr -s- und diese Schwierigkeit tritt nur dann auf, wenn Dateien verschiedener Typen außer regulären und / oder anderen Zeichensätzen als Ihrem nativen verwendet werden und / oder die Das ursprüngliche Archiv wurde durch eine Implementierung mit Formatanwendungs-Eigenheiten erstellt, auf die Sie nicht vorbereitet sind. Und dies berührt nur die grundlegenden, standardisierten Aspekte dertar Archivtyps - fügen Sie erweiterte Header und Formaterweiterungen sowie spärliche Dateien und Komprimierungen hinzu und ... nun, viel Glück damit.

Zurück zu den Wurzeln, aber die Standard - Datensatz -Größe für ein tarArchiv ist 20 Blöcke - oder 10.240 Bytes. Wenn ein Archiv mit der Standarddatensatzgröße blockiert ist und nur Standarddateitypen und Standardheader enthält ustar, sollten Sie jedoch von Member-Header zu Member-Header springen, indem Sie gemäß dem sizeHeader-Feld lesen, bis Sie ein Mitglied finden, das dem für entspricht was du suchst. Dort können Sie sizeBytes ab dem Offset einlesen, der am Ende des Member-Headers Ihres Ziels beginnt. Und das ist deine Akte.

Das Überspringen der Überschriften ist jedoch nicht besonders einfach. Bei verschiedenen Typen werden entweder tatsächliche Datenblöcke angehängt, die entsprechen size. Beispielsweise enthalten Verzeichnisse und Links keinen solchen Datenblock, sondern nur eine Header-Beschreibung. Daher müssen Sie bereit sein, den Dateityp des aktuellen Headers zu überprüfen, bevor Sie genau feststellen, ob Sie das sizeFeld auf Ihre Sprungformel anwenden sollen oder nicht.

Auch die Aufzeichnung -Größe Faktoren - je nachdem , ob die Archiv-Mitglieder Größen synchronisieren gut mit dem 10240 - Standard Rekord -größe es kann oder auch nicht ein zusätzlicher 0-Block jeweils angehängt werden kann. Die Datensatzgröße kann zum Zeitpunkt der Archiverstellung deklariert werden. Daher sind es möglicherweise nicht einmal 20 Blöcke, obwohl sie laut Spezifikation immer auf 512-Byte-Einheiten blockiert werden muss:

  • ustar
    • Das tarAustauschformat; Siehe den Abschnitt ERWEITERTE BESCHREIBUNG . Die Standard - Blockgröße für dieses Format für Zeichen spezielle Archivdateien wird seine 10.240 . Implementierungen müssen alle Blockgrößenwerte unterstützen , die kleiner oder gleich 32256 sind und ein Vielfaches von 512 sind .

Wenn Sie also mit einer tarDatei arbeiten, die möglicherweise Dateien enthält, die beliebige Binärdaten enthalten, müssen Sie die Datei algorithmisch und nach Dateityp überspringen. Die Spezifikation sagt:

  • Das sizeFeld hat die Größe der Datei in Oktetten.
    • Wenn für das typeflagFeld eine Datei vom Typ 1 (eine Verknüpfung ) oder 2 (eine symbolische Verknüpfung ) angegeben wird , wird das sizeFeld als Null angegeben.
    • Wenn für das typeflagFeld eine Datei vom Typ 5 ( Verzeichnis ) angegeben ist , ist das sizeFeld wie unter der Definition dieses Datensatztyps beschrieben zu interpretieren.
    • Für die Typen 1 , 2 oder 5 werden keine logischen Datensätze gespeichert .
    • Wenn das typeflagFeld auf 3 ( Zeichenspezialdatei ) , 4 ( Blockspezialdatei ) oder 6 ( FIFO ) eingestellt ist , wird die Bedeutung des sizeFelds in diesem Band von POSIX.1-2008 nicht angegeben, und es dürfen keine logischen Datensätze vorhanden sein auf dem Medium gespeichert.
    • Außerdem muss bei Typ 6 das sizeFeld beim Lesen ignoriert werden.
  • Wenn das typeflagFeld auf einen anderen Wert gesetzt ist, muss die Anzahl der nach dem Header geschriebenen logischen Datensätze so sein , dass ein Bruchteil des Ergebnisses der Division ignoriert wird.( (size+ 511 ) / 512 )

... und natürlich auch unter Berücksichtigung der individuellen Größe jedes Headers - ein zusätzlicher Block pro Mitglied. Sie können also das Lesen von Lesen von Kopfzeile zu Kopfzeile überspringen, bis Sie auf einer landen, die mit der gesuchten Kopfzeile übereinstimmt. Zu diesem Zeitpunkt müssten Sie dann prüfen, ob der aktuelle Datensatz lediglich einen Link zu Ihrer Datei oder zur tatsächlichen Datei beschreibt . Dies ist besonders relevant, da beim mehrmaligen Hinzufügen derselben Datei zu einem Archiv viele tars nur Link- Header enthalten, da die Daten der tatsächlichen Datei bereits an anderer Stelle im Archiv gefunden werden können.

Nachdem Sie überprüft haben, dass Sie Ihre Berechnungen auf das chksumFeld anwenden müssen, und überprüfen müssen, ob die Datei, die Sie zu haben glauben, tatsächlich die gewünschte Datei ist. tar's chksumist allerdings ziemlich einfach-:

  • cksum
    • Das chksumFeld muss die Standard-IRV-Darstellung nach ISO / IEC 646: 1991 des Oktalwerts der einfachen Summe aller Oktette im logischen Header-Datensatz sein. Jedes Oktett in der Kopfzeile wird als vorzeichenloser Wert behandelt. Diese Werte werden zu einer vorzeichenlosen Ganzzahl addiert, die auf Null initialisiert ist und deren Genauigkeit mindestens 17 Bit beträgt. Bei der Berechnung der Prüfsumme wird das chksumFeld so behandelt, als wären es alle <Leerzeichen> .

Natürlich würden Sie nicht wirklich irgendetwas davon zu tun haben, denn tarschon tun - das ist , was es tut - und so sollten Sie es wahrscheinlich nur verwenden , um das Archiv zu suchen und die Datei für Sie zu extrahieren. Dabei wird es nichts ganz anderes machen als Sie, wenn Sie wüssten, worum es Ihnen geht, außer dass es es wahrscheinlich besser und schneller macht, weil das seine Aufgabe ist. Und warum solltest du überhaupt?

mikeserv
quelle
0

Sie können diese Zeile verwenden

tar -axf a.tar -O
Tachomi
quelle
3
Dies zeigt alle Dateien im Teer an, nicht nur, y.txtund aus der Frage des OP geht nicht hervor, dass dies die einzige Datei im Teer ist.
Anthon