Dawid Grabowski's helpful answer is the way to go (with sed
[1]
; Ed Morton's helpful answer is a viable awk
alternative; a tail
+head
combination will typically be the fastest[2]).
As for why your approach didn't work:
A two-address expression such as 89001,89009
selects an inclusive range of lines, bounded by the start and end address (line numbers, in this case).
The associated function list, {p;q;}
, is then executed for each line in the selected range.
Thus, line # 89001
is the 1st line that causes the function list to be executed: right after printing (p
) the line, function q
is executed - which quits execution right away, without processing any further lines.
To prevent premature quitting, Dawid's answer therefore separates the aspect of printing (p
) all lines in the range from quitting (q
) processing, using two commands separated with ;
:
89001,89009p
prints all lines in the range
89009q
quits processing when the range's end point is reached
[1] A slightly less repetitive reformulation that should perform equally well ($
represents the last line, which is never reached due to the 2nd command):
sed -n '89001,$ p; 89009 q'
[2] A better reformulation of the head
+ tail
solution from Dawid's answer is
tail -n +89001 file | head -n 9
, because it caps the number of bytes that are not of interest yet are still sent through the pipe at the pipe-buffer size (a typical pipe-buffer size is 64 KB).
With GNU utilities (Linux), this is the fastest solution, but on OSX with stock utilities (BSD), the sed
solution is fastest.