Ось як це можна зробити:
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
.
Для цього використовується розмір блоку 64k, який часто є ідеальним. Всупереч поширеній думці, великі розміри блоків не роблять dd
роботу швидше. З іншого боку, крихітні буфери теж не корисні. dd
потрібно синхронізувати свій час у системних дзвінках, щоб не потрібно було чекати копіювання даних у пам'ять та знову, а також так, що не потрібно чекати на системні дзвінки. Отже, ви хочете, щоб це зайняло достатньо часу, щоб наступне read()
не довелося чекати останнього, але не настільки, щоб ви буферували більші розміри, ніж потрібно.
Тож перший dd
переходить до вихідної позиції. Це займає нуль часу. Ви можете зателефонувати будь-якій іншій програмі, яка вам сподобалася в цей момент, щоб прочитати її stdin, і вона почне читати безпосередньо у бажаному зміщенні байтів. Я закликаю іншого dd
для читання ((interval / blocksize) -1)
лічильних блоків до stdout.
Останнє, що потрібно - це скопіювати модуль (якщо такий є) попередньої операції поділу. І це все.
Не повірте, до речі, коли люди констатують факти на обличчі без доказів. Так, можливо dd
зробити коротке читання (хоча такі речі неможливі при читанні зі здорового блокового пристрою - таким чином, назва) . Такі речі можливі лише в тому випадку, якщо ви неправильно буферизуєте dd
потік, який читається з іншого, ніж блочного пристрою. Наприклад:
cat data | dd bs="$num" ### incorrect
cat data | dd ibs="$PIPE_MAX" obs="$buf_size" ### correct
В обох випадках dd
копіюються всі дані. У першому випадку можливо (хоча навряд чи з cat
) , що деякі з вихідних блоків, dd
копіює волю біт , що дорівнює «$ Num» байти , тому що dd
це білд тільки в буфер взагалі нічого , якщо буфер НЕ буде запитано на його Command- рядок. bs=
представляє максимальний розмір блоку, оскільки мета введення dd
/ виводу в реальному часі.
У другому прикладі я чітко вказую розмір вихідного блоку і dd
буфери зчитуються до тих пір, поки не може бути здійснено повне записування. Це не впливає на те, count=
що базується на вхідних блоках, але для цього вам просто потрібен інший dd
. Будь-яка дезінформація, яка вам надана в іншому випадку, повинна не враховуватися.
bs=1M iflag=skip_bytes,count_bytes