Вот как вы можете сделать это:
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