Ich habe herausgefunden, dass Sie die Komprimierungsrate dramatisch erhöhen können, wenn Sie eine Liste von Dateien nach Dateierweiterung anstatt alphabetisch sortieren, bevor Sie sie in ein Tar-Archiv stellen (besonders bei großen Quellbäumen, in denen Sie wahrscheinlich viele .c haben, .o und .h Dateien).
Ich konnte keine einfache Möglichkeit finden, Dateien mit der Shell zu sortieren, die in jedem Fall so funktioniert, wie ich es erwarten würde. Eine einfache Lösung wie find | rev | sort | rev
erledigt den Job, aber die Dateien erscheinen in einer ungeraden Reihenfolge, und sie sind nicht so gut für die beste Komprimierungsrate angeordnet. Andere Tools wie ls -X
arbeiten nicht mit find
und sort -t. -k 2,2 -k 1,1
funktionieren nicht, wenn Dateien mehr als eine Periode im Dateinamen enthalten (z. B. Version 1.5.tar). Eine weitere Quick-n-dirty-Option, die sed
verwendet, ersetzt die letzte Periode durch eine /
(die niemals in einem Dateinamen vorkommt), sortiert dann und teilt sie entlang der /
:
Dies funktioniert jedoch nicht mehr mit der Ausgabe von find
, die in den Namen /
s hat, und alle anderen Zeichen (außer 0) sind in Dateinamen in * nix erlaubt.
Ich entdeckte, dass Sie mit Perl eine benutzerdefinierte Vergleichsunterroutine schreiben können, die dieselbe Ausgabe wie cmp
verwendet (ähnlich wie strcmp
in C) und dann die Perl-Sortierfunktion ausführt und Ihren eigenen benutzerdefinierten Vergleich übergibt einfach mit regulären Perl-Ausdrücken zu schreiben. Genau das habe ich getan: Ich habe jetzt ein Perl-Skript, das
Allerdings ist Perl nicht so portabel wie Bash, also möchte ich mit einem Shell-Skript umgehen können. Darüber hinaus fügt find
keine abschließenden / an Verzeichnisnamen ein, sodass das Skript Verzeichnisse als die gleichen wie Dateien ohne Erweiterung ansieht. Im Idealfall möchte ich, dass tar
zuerst alle Verzeichnisse liest, dann normale Dateien (und sortiert sie), dann symbolische Verknüpfungen, die ich über
aber ich stoße immer noch auf das Problem, dass ich entweder diese Monstrosität jedes Mal eingeben muss, oder ich habe sowohl ein Shell-Skript für diese lange Zeile als auch ein Perl-Skript zum Sortieren, und Perl ist nicht überall verfügbar, also stopf alles rein Ein Perl-Skript ist auch keine gute Lösung. (Ich konzentriere mich hauptsächlich auf ältere Computer, weil heutzutage alle modernen Linux- und OSX-Versionen mit einer neueren Version von Perl ausgeliefert werden).
Ich möchte in der Lage sein, alles in ein Shell-Skript zusammenzufassen, aber ich weiß nicht, wie ich eine benutzerdefinierte Funktion an das GNU-Sortierwerkzeug übergeben soll. Habe ich kein Glück und muss ein Perl-Skript verwenden? Oder kann ich das mit einem Shell-Skript machen?
EDIT: Danke für die Idee einer Schwartzan-Transformation. Ich habe eine etwas andere Methode verwendet, mit sed
. Meine letzte Sortierroutine ist wie folgt:
Hier werden Sonderzeichen (z. B. *) in Dateinamen behandelt und Dateien ohne eine Erweiterung zuerst abgelegt, da es sich oft um Textdateien handelt. (Makefile, KOPIEREN, README, konfigurieren, etc.).
P.S. Falls jemand meine ursprüngliche Vergleichsfunktion haben möchte oder denke, ich könnte sie verbessern, hier ist es:
%Vor%Wenn Sie mit Perl vertraut sind, können Sie auch eine Schwartzian Tranform in BASH verwenden.
Eine Schwartian Transformation fügt nur den gewünschten Sortierschlüssel zu Ihrer Sortierinformation hinzu, führt die Sortierung durch und entfernt dann den Sortierschlüssel. Es wurde von Randal Schwartz erstellt und wird stark in Perl verwendet. Es ist jedoch auch gut in anderen Sprachen zu verwenden:
Sie möchten Ihre Dateien nach Erweiterung sortieren:
%Vor% Ich lese jede Datei mit meinem find
. Ich verwende printf
, um meinen Dateinamen mit dem Suffix zu versehen, nach dem ich sortieren möchte. Dann mache ich meine Sorte. My awk
streift meine Sortier-Taste ab und lässt nur meinen Dateinamen zurück, der immer noch nach Suffix sortiert ist.
Nun enthält Ihre files_to_tar.txt
-Datei die Namen Ihrer Dateien, sortiert nach Suffix. Sie können den Parameter -T
von tar
verwenden, um die Namen der Dateien aus dieser Datei zu lesen:
Um nach der Erweiterung zu gruppieren ähnliche Dateien zu sortieren, und dann meine md5sum, um identische Dateien zu gruppieren:
%Vor%Anmerkung sort -k3,3 ist die Erweiterung sort, und die Standardsortierung "last resort" sortiert die Dateien nach md5sum.
Betrachte auch xz anstelle von gz, wenn du dir Sorgen um den Weltraum machst.