Ich habe ein Shell-Skript, in dem ich überprüfen muss, ob zwei Dateien dieselben Daten enthalten oder nicht. Ich mache dies für viele Dateien, und in meinem Skript diff
scheint der Befehl der Leistungsengpass zu sein.
Hier ist die Zeile:
diff -q $dst $new > /dev/null
if ($status) then ...
Könnte es eine schnellere Möglichkeit geben, die Dateien zu vergleichen, möglicherweise einen benutzerdefinierten Algorithmus anstelle des Standardalgorithmus diff
?
diff
undcmp
.Antworten:
Ich glaube,
cmp
wird beim ersten Byte Unterschied aufhören:quelle
cmp -s $old $new
funktioniert auch.-s
ist die Abkürzung für--silent
cmp
wird zuerst die Dateigröße überprüft. Hier ist die GNU-Version, wenn Sie die zusätzlichen Optimierungen sehen möchten, die sie enthält: git.savannah.gnu.org/cgit/diffutils.git/tree/src/cmp.cIch mag @Alex Howansky hat dafür 'cmp --silent' verwendet. Aber ich brauche sowohl positive als auch negative Antworten, also benutze ich:
Ich kann dies dann im Terminal oder mit einem SSH ausführen, um Dateien gegen eine konstante Datei zu prüfen.
quelle
echo success
Befehl (oder ein anderer Befehl, den Sie an seine Stelle gesetzt haben) fehlschlägt, wird Ihr Befehl "Negative Antwort" ausgeführt. Sie sollten ein "if-then-else-fi" -Konstrukt verwenden. Zum Beispiel wie dieses einfache Beispiel .Warum erhalten Sie nicht den Hash beider Dateiinhalte?
Probieren Sie dieses Skript aus, rufen Sie es beispielsweise script.sh auf und führen Sie es dann wie folgt aus: script.sh file1.txt file2.txt
quelle
1/(2^511)
. Wenn Sie sich keine Sorgen über jemanden machen, der absichtlich versucht, eine Kollision zu erzeugen, ist die Idee, dass diese Methode ein falsches Positiv erzeugt, kein ernstes Problem.cmp
ist jedoch immer noch effizienter, da nicht die gesamte Datei gelesen werden muss, wenn die Dateien nicht übereinstimmen.Da ich lutsche und nicht genug Reputationspunkte habe, kann ich diesen Leckerbissen nicht als Kommentar hinzufügen.
Wenn Sie jedoch den
cmp
Befehl verwenden möchten (und nicht ausführlich sein müssen / möchten), können Sie einfach den Exit-Status abrufen. Percmp
Manpage:Sie könnten also Folgendes tun:
quelle
cmp --silent $FILE1 $FILE2 ; if [ "$?" == "1" ]; then echo "files differ"; fi
die wiederum komplizierter ist,cmp --silent $FILE1 $FILE2 || echo "files differ"
da Sie den Befehl direkt im Ausdruck verwenden können. Es ersetzt$?
. Infolgedessen wird der vorhandene Status des Befehls verglichen. Und genau das macht die andere Antwort. Übrigens. Wenn jemand--silent
Probleme hat, wird es nicht überall unterstützt (Busybox). use-s
Für Dateien, die nicht unterschiedlich sind, muss für jede Methode beide Dateien vollständig gelesen werden, auch wenn der Lesevorgang in der Vergangenheit stattgefunden hat.
Es gibt keine Alternative. Um zu einem bestimmten Zeitpunkt Hashes oder Prüfsummen zu erstellen, muss die gesamte Datei gelesen werden. Große Dateien brauchen Zeit.
Das Abrufen von Dateimetadaten ist viel schneller als das Lesen einer großen Datei.
Gibt es also Dateimetadaten, mit denen Sie feststellen können, dass die Dateien unterschiedlich sind? Dateigröße ? oder sogar Ergebnisse des Dateibefehls, der nur einen kleinen Teil der Datei liest?
Beispielcodefragment für Dateigröße:
Wenn die Dateien dieselbe Größe haben, bleiben Sie beim vollständigen Lesen der Dateien hängen.
quelle
ls -n
diese Option , um Probleme zu vermeiden, wenn Benutzer- oder Gruppennamen Leerzeichen enthalten.Versuchen Sie auch, den Befehl cksum zu verwenden:
Der Befehl cksum gibt die Byteanzahl einer Datei aus. Siehe 'man cksum'.
quelle
md5
liest es trotzdem die gesamte Datei. Wenn Sie alsocmp
beim ersten Unterschied anhalten, ist dies viel schneller.Bei einigen Tests mit einem Raspberry Pi 3B + (ich verwende ein Overlay-Dateisystem und muss regelmäßig synchronisieren) habe ich einen eigenen Vergleich für diff -q und cmp -s durchgeführt. Beachten Sie, dass dies ein Protokoll aus / dev / shm ist, sodass die Geschwindigkeit des Festplattenzugriffs kein Problem darstellt:
Ich habe es ein paar Mal ausgeführt. cmp -s hatten auf der von mir verwendeten Testbox durchweg etwas kürzere Zeiten. Wenn Sie also cmp -s verwenden möchten, um Dinge zwischen zwei Dateien zu erledigen ...
quelle