David Grabowski's helpful answer is the way to go (with sed [1] ; Ed Morton's helpful answer is a viable alternative to awk ; The tail + head combination will usually be the fastest [2] ).
As for why your approach didn't work :
A bidirectional expression, such as 89001,89009 , selects an inclusive range of strings, limited by the start and end addresses (line numbers in this case).
The corresponding list of functions {p;q;} then executed for each row in the selected range.
Thus, line # 89001 is the first line that causes the list of functions to be executed: immediately after printing ( p ), the line is executed, the q function is executed - which immediately ends the execution, without processing any further lines.
To prevent a premature termination, Dawid's answer therefore separates the print aspect ( p ) of all lines in the range from processing completion ( q ) using two commands separated by ; :
89001,89009p prints all lines in a range89009q ends processing when the endpoint of the range is reached.
[1] A slightly less repetitive reformulation that should work equally well ( $ is the last line that is never reached due to the second command):
sed -n '89001,$ p; 89009 q'
[2] The best reformulation of the head + tail solution from David's answer is tail -n +89001 file | head -n 9 tail -n +89001 file | head -n 9 , because it overlaps the number of bytes that are of no interest, it is still sent through the channel in the size of the buffer-buffer (the typical size of the buffer-buffer is 64 KB). Using GNU utilities (Linux), this is the fastest solution, but on OSX with stock utilities (BSD), sed is the fastest.
source share