Ich versuche, Platz zu sparen, während ich ein "dummes" Backup mache, indem ich einfach Daten in eine Textdatei kopiere. Mein Backup-Skript wird täglich ausgeführt und sieht folgendermaßen aus:
- Erstellen Sie ein Verzeichnis, das nach dem Sicherungsdatum benannt ist.
- Speichern Sie einige Daten in einer Textdatei
"$name"
. - Wenn die Datei gültig ist, gzip sie :
gzip "$name"
. Ansonsten ,rm "$name"
.
Jetzt möchte ich einen zusätzlichen Schritt hinzufügen, um eine Datei zu entfernen, wenn dieselben Daten auch am Vortag verfügbar waren (und Symlink oder Hardlink erstellen).
Zuerst habe ich überlegt md5sum "$name"
, aber das funktioniert nicht, weil ich auch den Dateinamen und das Erstellungsdatum speichere.
Gibt gzip
es eine Option, um zwei komprimierte Dateien zu vergleichen und mir zu sagen, ob sie gleich sind oder nicht? Wenn gzip
es keine solche Option gibt, gibt es einen anderen Weg, um mein Ziel zu erreichen?
gzip
file-comparison
Lekensteyn
quelle
quelle
diff <(zcat file1) <(zcat file2)
, aber Mrethubs Vorschlagzdiff
sieht viel besser aus.Antworten:
Sie können
zcmp
oderzdiff
wie mreithub in seinem Kommentar vorschlägt (oder Kevins Befehl, der ähnlich ist) verwenden. Diese sind relativ ineffizient, da sie beide Dateien tatsächlich dekomprimieren und dann ancmp
oder weitergebendiff
. Wenn Sie nur antworten möchten, ob sie gleich sind, möchten Sie, dasscmp
es viel schneller geht.Ihr Ansatz mit dem
md5sum
ist vollkommen gut, aber Sie müssen den MD5 nehmen, bevor Sie laufengzip
. Speichern Sie es dann in einer Datei neben der resultierenden.gz
Datei. Sie können die Datei dann einfach vergleichen, bevor Sie sie komprimieren. Wenn der Name derselbe ist,md5sum -c
erledigen Sie dies für Sie.Und das nächste Backup:
Es hat sich also nicht geändert. OTOH, hatte es sich geändert:
Wenn Sie
--quiet
es übergeben, erhalten Sie nur den Exit-Code. 0 für übereinstimmend, nicht 0 für unterschiedlich.MD5 ist ziemlich schnell, aber nicht besonders schnell. MD4 (
openssl md4
ist das Beste, was Sie in der Befehlszeile erhalten, glaube ich) ist ungefähr doppelt so schnell (weder es noch MD5 sind sicher, aber beide sind ungefähr so kollisionssicher, wenn niemand versucht, sie zu untergraben). SHA-1 (sha1sum
) ist sicherer, aber langsamer. SHA-256 (sha256sum
) ist sicher, aber noch langsamer. CRC32 sollte um ein Vielfaches schneller sein, ist jedoch kürzer und weist daher mehr zufällige Kollisionen auf. Es ist auch völlig unsicher.quelle
zdiff
scheint eine Verschwendung zu sein, da ich nur wissen möchte, ob sich eine Datei geändert hat, nicht was .zcmp
sieht interessant aus, das werde ich versuchen.Die Antwort von @derobert ist großartig, obwohl ich einige andere Informationen teilen möchte, die ich gefunden habe.
gzip -l -v
gzip-komprimierte Dateien enthalten bereits einen Hash (allerdings nicht sicher, siehe diesen SO-Beitrag ):
Man kann CRC und unkomprimierte Größe kombinieren, um einen schnellen Fingerabdruck zu erhalten:
cmp
Verwenden Sie zum Überprüfen, ob zwei Bytes gleich sind oder nicht
cmp file1 file2
. Jetzt hat eine komprimierte Datei einen Header mit angehängten Daten und Fußzeilen (CRC plus Originalgröße). Die Beschreibung des gzip-Formats zeigt, dass der Header die Zeit enthält, zu der die Datei komprimiert wurde, und dass der Dateiname eine nicht terminierte Zeichenfolge ist, die nach dem 10-Byte-Header angehängt wird.Unter der Annahme, dass der Dateiname konstant ist und derselbe Befehl (
gzip "$name"
) verwendet wird, kann überprüft werden, ob zwei Dateien unterschiedlich sind, indemcmp
die ersten Bytes einschließlich der Zeit verwendet und übersprungen werden:Hinweis : Die Annahme, dass dieselben Komprimierungsoptionen wichtig sind, andernfalls meldet der Befehl die Datei immer als unterschiedlich. Dies liegt daran, dass die Komprimierungsoptionen im Header gespeichert sind und sich auf die komprimierten Daten auswirken können.
cmp
betrachtet nur rohe Bytes und interpretiert es nicht als gzip.Wenn Sie Dateinamen gleicher Länge haben, können Sie versuchen, die zu überspringenden Bytes nach dem Lesen des Dateinamens zu berechnen. Wenn die Dateinamen unterschiedlich groß sind, können Sie
cmp
nach dem Überspringen von Bytes wie zcmp <(cut -b9- file1) <(cut -b10- file2)
.zcmp
Dies ist definitiv der beste Weg, es komprimiert zuerst Daten und beginnt, die Bytes mit zu vergleichen
cmp
(wirklich, das ist, was imzcmp
(zdiff
) Shellscript gemacht wird).Ein Hinweis, haben Sie keine Angst vor dem folgenden Hinweis auf der Handbuchseite:
Wenn Sie einen ausreichend neuen Bash haben, wird bei der Komprimierung keine temporäre Datei verwendet, sondern nur eine Pipe. Oder wie die
zdiff
Quelle sagt:quelle
gzip -v -l
dass die Dateizeit anstelle von MTIME gemeldet wird, wenn die vier MTIME-Bytes im Header Null sind. Beachten Sie auch, dass MTIME in der Regel etwas vor der Dateizeit liegt, da die Komprimierung gestartet wurde.Um zwei gzip-Dateien zu vergleichen, nur den Inhalt, einen Befehl, nein
diff
, nur vergleichenmd5sum
Sie können auch nach relevanten Unterschieden "filtern",
Bei Skripten würde ich eine Filterfunktion empfehlen (nicht getestet, nur ein Beispiel),
quelle
cmp
.zcat
undgrep
kann in zusammengeführt werdenzgrep
.zcat
ist gerechtgunzip -c
. Verwenden Sie das richtige Werkzeug für den richtigen Job, KISS ist besser als aufblähen. In diesem Fall würde ich meine Zeit damit verbringen, etwas zu schreiben, das bei Bedarf harte Links generiert. Das macht mehr Spaß.