Якщо ви хочете, щоб рядки від X до Y включали (починаючи нумерацію з 1), використовуйте
tail -n +$X /path/to/file | head -n $((Y-X+1))
tail
прочитає та відкине перші рядки X-1 (цього не обійти), потім прочитає та надрукує наступні рядки. head
прочитає та надрукує потрібну кількість рядків, а потім вийде. Коли head
виходить, tail
отримує сигнал SIGPIPE і вмирає, тому з вхідного файлу він не буде прочитати більше, ніж розмір буфера (як правило, кілька кілобайт) рядків.
Як варіант, запропонований gorkypl , використовуйте sed:
sed -n -e "$X,$Y p" -e "$Y q" /path/to/file
Рішення sed є значно повільнішим (принаймні, для утиліт GNU та утиліт Busybox; sed може бути більш конкурентоспроможним, якщо витягнути велику частину файлу в ОС, де трубопровід повільний, а sed швидкий). Ось швидкі орієнтири під Linux; дані генеруються seq 100000000 >/tmp/a
, середовище Linux / amd64, /tmp
є tmpfs, і машина в іншому випадку не працює і не замінюється.
real user sys command
0.47 0.32 0.12 </tmp/a tail -n +50000001 | head -n 10 #GNU
0.86 0.64 0.21 </tmp/a tail -n +50000001 | head -n 10 #BusyBox
3.57 3.41 0.14 sed -n -e '50000000,50000010 p' -e '50000010q' /tmp/a #GNU
11.91 11.68 0.14 sed -n -e '50000000,50000010 p' -e '50000010q' /tmp/a #BusyBox
1.04 0.60 0.46 </tmp/a tail -n +50000001 | head -n 40000001 >/dev/null #GNU
7.12 6.58 0.55 </tmp/a tail -n +50000001 | head -n 40000001 >/dev/null #BusyBox
9.95 9.54 0.28 sed -n -e '50000000,90000000 p' -e '90000000q' /tmp/a >/dev/null #GNU
23.76 23.13 0.31 sed -n -e '50000000,90000000 p' -e '90000000q' /tmp/a >/dev/null #BusyBox
Якщо ви знаєте діапазон байтів, з яким ви хочете працювати, ви можете витягнути його швидше, перейшовши безпосередньо в початкове положення. Але для рядків потрібно читати з початку і рахувати нові рядки. Для вилучення блоків від x включно до y виключно, починаючи з 0, розмір блоку b:
dd bs=$b seek=$x count=$((y-x)) </path/to/file