Wie kann man so etwas dd if=somefile bs=1 skip=1337 count=31337000
effizient machen, ohne 1-Byte-Lese- und Schreibvorgänge zu verwenden?
Als Lösung wird erwartet:
- Um es einfach zu halten (für nicht einfache Dinge kann ich einen Perl-Oneliner schreiben, der das erledigt)
- Um große Offsets und Längen zu unterstützen (Hacks mit Blockgröße in dd helfen also nicht)
Teillösung (nicht einfach genug, der Versuch mit der Länge macht es noch komplizierter):
dd if=somefile bs=1000 skip=1 count=31337 | { dd bs=337 count=1 of=/dev/null; rest_of_pipeline; }
# 1337 div 1000 and 1337 mod 1000
Antwort1
Dies sollte funktionieren (unter GNU DD):
dd if=somefile bs=4096 skip=1337 count=31337000 iflag=skip_bytes,count_bytes
Falls Sie seek=
auch verwenden, können Sie auch Folgendes in Betracht ziehen oflag=seek_bytes
.
Aus info dd
:
`count_bytes'
Interpret the `count=' operand as a byte count, rather than a
block count, which allows specifying a length that is not a
multiple of the I/O block size. This flag can be used only
with `iflag'.
`skip_bytes'
Interpret the `skip=' operand as a byte count, rather than a
block count, which allows specifying an offset that is not a
multiple of the I/O block size. This flag can be used only
with `iflag'.
`seek_bytes'
Interpret the `seek=' operand as a byte count, rather than a
block count, which allows specifying an offset that is not a
multiple of the I/O block size. This flag can be used only
with `oflag'.
P.S.: Mir ist bewusst, dass diese Frage alt ist und diese Flags anscheinend erst nach der ursprünglichen Fragestellung implementiert wurden, da es sich aber um eines der ersten Google-Ergebnisse für eine von mir durchgeführte entsprechende DD-Suche handelt, dachte ich, es wäre schön, ein Update mit der neuen Funktion durchzuführen.
Hinweis: Diese Antwort gilt nur fürGNU dd, wird von den meisten Linux-Distributionen verwendet und ist Teil vonGNU Coreutils-Paket, diese Funktion wurde mit der Coreutils-Version 8.16 (26.03.2012, ein paar Monate nachdem die ursprüngliche Frage beantwortet wurde) eingeführt.
Hinweis fürMac-Benutzer: MacOS verwendet eine auf BSD basierende Variante von Unix-Utilities (hauptsächlich aus Lizenzgründen), aber GNU-Versionen von Unix-Utilities werden im Allgemeinen viel aktiver weiterentwickelt und verfügen normalerweise über viel mehr Funktionen. Sie können GNU Coreutils auf dem Mac installieren mitSelbstgebrautes: brew install coreutils
.
Antwort2
Verwenden Sie einen Prozess, um alle anfänglichen Bytes zu löschen, und dann einen zweiten, um die eigentlichen Bytes zu lesen, z. B.:
echo Hello, World\! | ( dd of=/dev/null bs=7 count=1 ; dd bs=5 count=1 )
Der zweite dd
kann die Eingabe mit der Blockgröße lesen, die Sie für effizient halten. Beachten Sie, dass hierfür ein zusätzlicher Prozess gestartet werden muss. Abhängig von Ihrem Betriebssystem verursacht dies Kosten, ist aber wahrscheinlich geringer, als wenn Sie die Dateien Byte für Byte lesen müssten (es sei denn, Sie haben eine sehr kleine Datei, in diesem Fall wäre das kein Problem).
Antwort3
Statt zu bs=1
verwenden bs=4096
oder mehr.
Antwort4
Sie können den Befehl „Hexdump“ ausprobieren:
hexdump -v <File Path> -c -n <No of bytes to read> -s <Start Offset>
Wenn Sie einfach nur den Inhalt sehen möchten:
#/usr/bin/hexdump -v -C mycorefile -n 100 -s 100
00000064 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000074 00 00 00 00 01 00 00 00 05 00 00 00 00 10 03 00 |................|
00000084 00 00 00 00 00 00 40 00 00 00 00 00 00 00 00 00 |......@.........|
00000094 00 00 00 00 00 00 00 00 00 00 00 00 00 a0 03 00 |................|
000000a4 00 00 00 00 00 10 00 00 00 00 00 00 01 00 00 00 |................|
000000b4 06 00 00 00 00 10 03 00 00 00 00 00 00 90 63 00 |..............c.|
000000c4 00 00 00 00 |....|
000000c8 #