Heute musste ich die ersten 1131 Bytes aus einer 800 MB großen gemischten Text- / Binärdatei entfernen, einem gefilterten Subversion-Dump, den ich für ein neues Repository hacke. Wie geht das am besten?
Zunächst habe ich versucht
dd bs=1 skip=1131 if=filtered.dump of=trimmed.dump
Nach dem Überspringen wird jedoch der Rest der Datei jeweils byteweise kopiert, dh sehr langsam. Am Ende habe ich herausgefunden, dass ich 405 Bytes benötigte, um dies auf drei 512er Blöcke aufzurunden, die ich überspringen konnte
dd if=/dev/zero of=405zeros bs=1 count=405
cat 405zeros filtered.dump | dd bs=512 skip=3 of=trimmed.dump
Was ist ziemlich schnell erledigt, aber es muss einen einfacheren / besseren Weg gegeben haben? Gibt es ein anderes Tool, das ich vergessen habe? Vielen Dank!
dd
ist das richtige Werkzeug für den Job - anscheinend haben Sie eine schöne, elegante Lösung für Ihr Problem gefunden.Antworten:
Sie können bs wechseln und Optionen überspringen:
Auf diese Weise kann die Operation von einem größeren Block profitieren.
Andernfalls könnten Sie es mit tail versuchen (obwohl es nicht sicher ist, es mit Binärdateien zu verwenden):
Schließlich können Sie 3 dd-Instanzen verwenden, um so etwas zu schreiben:
wo die erste dd druckt seine Standardausgabe gefiltert.dump; der zweite liest gerade 1131 Bytes und wirft sie weg; Dann liest der letzte die verbleibenden Bytes von filters.dump von seiner Standardeingabe und schreibt sie in trimmed.dump.
quelle
bs=1131 skip=1
: - /Nicht sicher, wann
skip_bytes
hinzugefügt wurde, aber um die ersten 11 Bytes zu überspringen, haben Sie:Wobei
iflag=skip_bytes
dd angewiesen wird, den Wert für dieskip
Option als Bytes anstelle von Blöcken zu interpretieren , um dies unkompliziert zu gestalten.quelle
iflag=skip_bytes skip=1234 bs=1M
Sie können eine Sub-Shell und zwei
dd
Aufrufe wie folgt verwenden:quelle
Wenn das Dateisystem und der Linux-Kernel dies unterstützen, können Sie versuchen
fallocate
, die Änderungen zu übernehmen: Im besten Fall gibt es überhaupt keine Daten-E / A:Wo
<magic>
hängt vom Dateisystem, der Linux-Version und dem Dateityp ab (FALLOC_FL_COLLAPSE_RANGE
oderFALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE
kann intern verwendet werden ).quelle
Sie sollten verwenden
count=0
- das ist einfach,lseek()
wann immer es möglich ist.So was:
dd
wirdlseek()
der Eingang Dateideskriptor zu einem 1131 - Byte - Offset, und danncat
wird einfach kopieren , was zur Ausgabe bleibt.quelle
Ein weiterer Weg führt Bytes aus der Datei zu entfernen (ohne die Verwendung von
dd
überhaupt) zu verwenden ist,xxd
undsed
odertail
ist.quelle
@maxschlepzig fragt nach einem Online-Liner. Hier ist einer in Perl. Es braucht 2 Argumente: Von Byte und Länge. Die Eingabedatei muss mit '<' angegeben werden und die Ausgabe erfolgt auf stdout:
Ist die Länge größer als die Datei, wird der Rest der Datei kopiert.
Auf meinem System liefert dies 3,5 GB / s.
quelle
dd
ein vollständiger Lesevorgang nicht garantiert. Versuchen Sie: ja | dd bs = 1024k count = 10 | wc unix.stackexchange.com/questions/17295/…