Вот как вы можете сделать это:
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
Это все, что действительно необходимо - это не требует намного большего. На первом месте dd count=0 skip=1 bs=$block_size1
будет lseek()
обычный ввод файлов практически мгновенно. Там нет шансов пропущенных данных или любой другой неправды об этом, вы можете просто искать прямо к вашей желаемой стартовой позиции. Поскольку файловый дескриптор принадлежит оболочке и dd
они просто наследуют его, они будут влиять на его положение курсора, поэтому вы можете просто выполнить его пошагово. Это действительно очень просто - и нет стандартного инструмента, лучше подходящего для этой задачи, чем dd
.
Это использует размер блока 64 КБ, который часто идеален. Вопреки распространенному мнению, большие размеры блоков не заставляют dd
работать быстрее. С другой стороны, крошечные буферы тоже не годятся. dd
ему нужно синхронизировать свое время в системных вызовах, чтобы ему не нужно было ждать при копировании данных в память и снова, а также чтобы не нужно было ждать системных вызовов. Таким образом, вы хотите, чтобы это заняло достаточно времени, чтобы следующий read()
не должен был ждать последнего, но не настолько, чтобы вы буферизировали в больших размерах, чем это необходимо.
Итак, первый dd
переходит на стартовую позицию. Это занимает нулевое время. Вы можете вызвать любую другую программу, которая вам нравится в этот момент, чтобы прочитать ее стандартный вывод, и она начнет читать непосредственно с желаемым байтовым смещением. Я звоню другому, dd
чтобы прочитать ((interval / blocksize) -1)
количество блоков в стандартный вывод.
Последнее, что необходимо, это скопировать модуль (если есть) предыдущей операции деления. И это все.
Кстати, не верьте этому, когда люди заявляют факты на лице без доказательств. Да, это возможно для dd
краткого чтения (хотя такие вещи невозможны при чтении с исправного блочного устройства - таким образом, имя) . Такое возможно только в том случае, если вы неправильно буферизуете dd
поток, который читается не с блочного устройства. Например:
cat data | dd bs="$num" ### incorrect
cat data | dd ibs="$PIPE_MAX" obs="$buf_size" ### correct
В обоих случаях dd
копируются все данные. В первом случае возможно (хотя и маловероятно,cat
что ), что некоторые из выходных блоков, которые dd
копируются, будут равны байтам «$ num», потому что dd
спецификация предназначена только для буферизации чего-либо вообще, когда буфер специально запрашивается по его команде. линия. bs=
представляет собой максимальный размер блока , так как цель из dd
в реальном времени ввода / вывода.
Во втором примере я явно указываю выходной размер блока и dd
буферизует чтение до тех пор, пока не будут выполнены полные записи. Это не влияет на то, count=
что основано на входных блоках, но для этого вам просто нужен другой dd
. Любая дезинформация, предоставленная вам в противном случае, должна игнорироваться.
bs=1M iflag=skip_bytes,count_bytes