
Ich habe eine sehr große Datei (200 GB). Anscheinend wurde sie beim Übertragen nicht richtig kopiert. Der SHA1-Hash ist auf beiden unterschiedlich. Gibt es eine Möglichkeit, die Datei in Blöcke (z. B. 1 MB oder 64 MB) aufzuteilen und für jeden Block einen Hash auszugeben? Dann vergleichen/korrigieren?
Vielleicht schreibe ich einfach schnell eine App dafür.
Antwort1
Diese „schnelle App“ gibt es bereits und sie ist relativ weit verbreitet: rsync. Natürlich kann rsync noch viel mehr, aber was Sie wollen, ist ziemlich einfach:
rsync -cvP --inplace user@source:src-path-to-file dest-path-to-file # from the destination
rsync -cvP --inplace src-path-to-file user@dest:dest-path-to-file # from the source
Standardmäßig wird ssh (oder bei einer sehr alten Version rsh) verwendet, um die Verbindung herzustellen und die Daten zu übertragen. Andere Methoden sind ebenfalls möglich.
Die von mir übergebenen Optionen sind:
-c
– Überspringen basierend auf Prüfsummen, nicht Dateigröße/Mtime. Standardmäßig optimiert und überspringt rsync Übertragungen, bei denen Größe und Mtime übereinstimmen.-c
zwingt es, die Prüfsumme zu berechnen (was in Bezug auf E/A eine aufwändige Operation ist). Beachten Sie, dass dies eine blockbasierte Prüfsumme ist (es sei denn, Sie weisen es an, nur ganze Dateien zu verarbeiten) und es werden nur die beschädigten Blöcke übertragen. Die Blockgröße wird automatisch gewählt, kann aber überschrieben werden-B
(ich bezweifle, dass es dafür einen Grund gibt).-v
— ausführlich, gibt einige Details an (an welcher Datei gearbeitet wird)-P
— aktiviert sowohl teilweise Dateien (damit die Arbeit nicht weggeworfen wird, wenn die Arbeit zur Hälfte fertig ist) als auch einen Fortschrittsbalken.--inplace
— Aktualisieren Sie die vorhandene Datei, nicht eine temporäre Datei (die dann die Originaldatei ersetzen würde). So sparen Sie sich eine temporäre Datei mit 200 GB. Impliziert auch Teildateien, was-P
teilweise redundant ist.
Übrigens: Ich bin nicht sicher, wie Sie die ursprüngliche Übertragung durchgeführt haben, aber wenn es SFTP/SCP war, stimmt etwas nicht – diese schützen vollständig vor Beschädigungen im Netzwerk. Sie sollten wirklich die Ursache herausfinden. Defekter RAM ist ein relativ häufiges Problem.
Antwort2
Wenn Sie die Datei über eine Netzwerkverbindung auf einen anderen Rechner übertragen möchten,Verwenden Sie rsync.
Wenn Sie sich ein Bild von den Unterschieden machen möchten, ist es am einfachsten, die beiden Versionen auf derselben Maschine zu haben. Wenn Sie das nicht möchten, weil die Bandbreite zu teuer ist, können Sie auf folgende Weise Dateiblöcke überprüfen.
Bei dieser Methode wird head -c
die Dateiposition dort belassen, wo sie aufgehört hat, und die Größe wird vorab berechnet, um zu wissen, wo die Schleife enden soll.
n=$(($(wc -c <very_large_file) / (64*1024*1024) + 1))
i=0
while [ $i -gt $n ]; do
head -c 64m | sha256sum
i=$((i+1))
done <very_large_file
Bei dieser Methode wird head -c
die Dateiposition dort belassen, wo sie aufgehört hat, und sie wird verwendet, cksum
um die Größe jedes Blocks zu ermitteln (ein kurzer Block zeigt das Ende der Datei an).
while true; do
output=$(head -c 64m | cksum)
size=${output#* }; size=${output%% *}
if [ $size -eq 0 ]; then break; fi
echo "$output"
done <very_large_file
Diese Methode ruft dd
den Sprung zur gewünschten Startposition für jeden Block auf.
n=$(($(wc -c <very_large_file) / (64*1024*1024) + 1))
i=0
while [ $i -gt $n ]; do
dd if=very_large_file ibs=64m skip=$i count=1 | sha256sum
i=$((i+1))
done <very_large_file
Antwort3
Sie sollten sich wahrscheinlich Folgendes ansehen split
:
Hier ist die Manpage mit Beispielen: