So kannst du das machen:
i=$(((t=19876543212)-(h=12345678901)))
{ dd count=0 skip=1 bs="$h"
dd count="$((i/(b=64*1024)-1))" bs="$b"
dd count=1 bs="$((i%b))"
} <infile >outfile
Das ist alles, was wirklich notwendig ist - es erfordert nicht viel mehr. In erster Linie dd count=0 skip=1 bs=$block_size1
wird lseek()
über regelmäßige Dateieingabe praktisch augenblicklich. Es besteht keine Möglichkeit, dass Daten übersehen werden oder andere Unwahrheiten darüber gemeldet werden. Sie können einfach direkt zu Ihrer gewünschten Startposition suchen. Da der Dateideskriptor der Shell gehört und die Shell ihn dd
lediglich erbt, wirkt er sich auf die Cursorposition aus, sodass Sie ihn schrittweise ausführen können. Es ist wirklich sehr einfach - und es gibt kein Standardwerkzeug, das besser für die Aufgabe geeignet ist als dd
.
Dafür wird eine Blockgröße von 64 KB verwendet, was häufig ideal ist. Entgegen der landläufigen Meinung beschleunigen größere Blockgrößen die dd
Arbeit nicht . Andererseits sind winzige Puffer auch nicht gut. dd
muss seine Zeit in Systemaufrufen synchronisieren, damit es nicht warten muss, bis Daten in den Speicher kopiert und wieder ausgegeben werden, sondern auch, damit es nicht auf Systemaufrufe warten muss. Sie möchten also, dass es genügend Zeit in Anspruch read()
nimmt , damit der nächste nicht auf den letzten warten muss, sondern nicht so viel, dass Sie in größeren Formaten als erforderlich puffern.
Der Erste dd
springt also zur Startposition. Das braucht keine Zeit. Sie können jedes andere Programm aufrufen, das Sie an diesem Punkt mochten, um seine Standard-ID zu lesen, und es würde direkt an Ihrem gewünschten Byte-Offset mit dem Lesen beginnen. Ich rufe einen anderen dd
an, um ((interval / blocksize) -1)
count blocks to stdout zu lesen .
Das letzte, was notwendig ist, ist das Herauskopieren des Moduls (falls vorhanden) der vorherigen Divisionsoperation. Und das ist das.
Glauben Sie es übrigens nicht, wenn die Leute Tatsachen ohne Beweise auf ihrem Gesicht ausdrücken. Ja, es ist möglich dd
, einen kurzen Lesevorgang durchzuführen (obwohl dies beim Lesen von einem fehlerfreien Blockgerät nicht möglich ist - daher der Name) . Solche Dinge sind nur möglich, wenn Sie einen dd
Stream, der nicht von einem Block-Gerät gelesen wird, nicht korrekt puffern . Beispielsweise:
cat data | dd bs="$num" ### incorrect
cat data | dd ibs="$PIPE_MAX" obs="$buf_size" ### correct
In beiden Fällen werden alle Daten dd
kopiert . Im ersten Fall ist es möglich (wenn auch unwahrscheinlich ) , dass einige der Ausgangsblöcke , die Kopien aus Willen gleich „$ num“ Bit - Bytes , weil geskilled wird nur überhaupt etwas zu puffern , wenn der Puffer speziell auf ihre Kommando- angefordert wird Linie. stellt eine maximale Blockgröße dar, da der Zweck von Echtzeit-E / A ist.cat
dd
dd
bs=
dd
Im zweiten Beispiel gebe ich explizit die Ausgabeblockgröße und die Pufferlesungen an, dd
bis vollständige Schreibvorgänge durchgeführt werden können. Das wirkt sich nicht darauf aus, count=
welche auf Eingabeblöcken basieren, aber dafür brauchen Sie einfach einen anderen dd
. Jegliche Fehlinformationen, die Sie ansonsten erhalten, sollten ignoriert werden.
bs=1M iflag=skip_bytes,count_bytes