Wie erstelle ich eine Tar-Datei in alphabetischer Reihenfolge?

22

Ich möchte eine TAR-Datei erstellen, in der alle Verzeichnisse und Dateien in alphabetischer Reihenfolge verarbeitet werden. Dies gilt für die gesamte Verzeichnishierarchie, die gerade geteert wird. Daher wird zunächst das erste Verzeichnis alphabetisch verarbeitet und dann die Unterverzeichnisse in alphabetischer Reihenfolge usw. Ich habe die Manpage durchgesehen und kann keinen Schalter dafür finden.

Ich gebe zu, das ist halb Neuheit, halb leichte Optimierung. Ich kann einfach nicht glauben, dass es keinen einfachen Weg gibt, dies zu tun. Ich muss etwas vermissen.

Erick Robertson
quelle
2
Warum willst du das machen?
Matthias Krull
Meistens, weil ich wissen will, wie kurz die Teeroperation vor dem Abschluss steht. Wenn die Dateien in zufälliger Reihenfolge geladen werden, können Sie dies nicht mit dem Flag -v feststellen.
Erick Robertson
2
Das ist nicht ganz richtig. Wenn Sie die Ausgabe an eine Datei leiten und die Anzahl der Dateien kennen (z. B. einen Befehl zum schnellen Suchen), können Sie die Ausgabe -v (wc -l) mit der Anzahl der Dateien aus find vergleichen, um einen Eindruck vom Fortschritt zu erhalten ...
Slartibartfast
2
@matthiaskrull Ich habe keinen Grund dafür. Ich erstelle eine OVA-Datei (eine Tar-Datei) für die Bereitstellung von VMs auf VMWare ESX Server. Die OVA benötigt Dateien in einer bestimmten Reihenfolge (Die erste Datei sollte eine OVF sein usw.).
Xask
1
Dafür gibt es auch einen sehr guten Grund: die Leistung einer sehr großen Datei, wenn Sie nur einen Teil davon extrahieren möchten. Da die Reihenfolge standardmäßig zufällig ist und Sie eine Datei / ein Verzeichnis extrahieren möchten, muss das gesamte Archiv gescannt werden, bevor bekannt ist, dass es fertig ist.
StormByte

Antworten:

12

Slartibartfast ist auf dem richtigen Weg, aber das Standardverhalten von tar besteht darin, in Verzeichnisse zu gelangen, sodass Sie möglicherweise mehr als eine Kopie derselben Datei in der generierten tar-Datei erhalten. Sie können dies überprüfen, indem Sie Folgendes tun: tar tf file.tar | sort Die Problemumgehung besteht darin, die Option --no-recursion to tar einzuschließen. Außerdem sollten Sie in der Lage sein, seltsame Dateinamen einzusenden, indem Sie die -print0 Option zum Suchen und dann die --nullOption zum Tarieren verwenden. Das Endergebnis sieht so aus:

find paths -print0 | sort -z | tar cf tarfile.tar --no-recursion --null -T -

Sie können die Reihenfolge in der TAR-Datei überprüfen, indem Sie verwenden tar tsf tarfile.tar. Obwohl Sie die Optionen -print0, -z und --null wahrscheinlich nie benötigen, es sei denn, Sie wissen, dass Sie auf einen Dateinamen mit einer darin eingebetteten neuen Zeile stoßen, habe ich es nie versucht.

Charlie Herron
quelle
Ausgezeichneter Vorschlag für die Verwendung der Option --no-recursion, danke.
Erik
Dies ist die Lösung, die für mich funktioniert hat. Ich habe einen anderen Anwendungsfall als Erick und Google hat mich hierher gebracht. Ich sammle Schnappschüsse über den vollständigen Status eines Remote-Systems. Die Daten sind hochgradig redundant. Das Sortieren des eingegebenen Teers nach der Zeit (Dateinamen haben einen Zeitstempel) verbessert die Leistung des Kompressors. Ein Schnelltest zeigt eine Verbesserung um den Faktor 2 (lzma2). Außerdem entpacke ich das Archiv nicht in ein Dateisystem, sondern führe eine Stream-Verarbeitung über tar-Einträge durch. Ein sortierter Stream macht die Debug-Ausgabe viel angenehmer und bietet weitere Vorteile in der Prozesskette. +1
Johannes
5

Die Reihenfolge der Dateien in der TAR-Datei spielt keine Rolle, da das Dateisystem die Reihenfolge beim Extrahieren der Dateien ohnehin nicht beibehält.

Es gibt keinen Schalter dafür, aber wenn Sie es wirklich wollten, könnten Sie tar eine Liste von Dateinamen in sortierter Reihenfolge zur Verfügung stellen und die tar-Datei in der Reihenfolge erstellen, in der Sie sie angeben.

% tar cf tarfile tmp/diff.txt src/hellow.c junkimage.IMG barry/thegroup
% tar tf tarfile
tmp/diff.txt
src/hellow.c
junkimage.IMG
barry/thegroup
Kevin Panko
quelle
2
oder sortieren Sie einfach die Ausgabe:tar tf tarfile | sort
Doug Harris
Ich habe viel zu viele Dateien (über 20.000), um sie alle in der Befehlszeile anzugeben.
Erick Robertson
4
Die Reihenfolge der Dateien in der TAR-Datei spielt eine Rolle, wenn Sie während des Herunterladens dekomprimieren und anzeigen müssen.
Erik
Hängt vom Dateisystem ab.
Thorbjørn Ravn Andersen
4

Vorausgesetzt, Sie haben keine Dateien mit Zeilenumbrüchen im Namen:

find /source_directory -print | sort | tar -czf target.tgz -T -

Wenn das nicht funktioniert (habe es nie ausprobiert, daher weiß ich nicht - bedeutet stdin für das -T-Argument):

find /source_directory -print | sort > /tmp/temporary_file_list
tar -czf target.tgz -T /tmp/temporary_file_list

Dann ist da die Frage warum. Aber manchmal ist es einfacher, nicht zu fragen.

Slartibartfast
quelle
2
find . -depth -print0 | sort -z | pax -wvd0 > file.tar

Pax ist sozusagen der POSIX-Nachfolger von cpio und tar und verschmilzt die besten Aspekte von beiden. Standardmäßig werden tar-Archive (ustar) geschrieben. Außerdem werden Medien automatisch durchsucht und abgefragt. Anschließend wird eine Zusammenfassung gedruckt.

Thomas Crescenzi
quelle
0

Alternativ zu @ CharlieHerrons Antwort möchten Sie möglicherweise Ordner aus der findAusgabe herausfiltern, wenn Sie nur Inhalte (Dateien, Symlinks) und Ordner-Metadaten (z. B. Ordnerberechtigungen, Mtime usw.) beibehalten möchten .

find paths -not -type d -print 0 | sort -z | tar cf tarfile.tar --null -T -
user1202136
quelle