my @line_nums = (44, 87, 345);
my $line_num = shift(@line_nums);
my $more = 2;
while (<>) {
next if $. != $line_num;
print;
if ($more) {
--$more;
++$line_num;
shift(@line_nums) if @line_nums && $line_nums[0] == $line_num;
next;
}
last unless @line_nums;
$line_num = shift(@line_nums);
$more = 2;
}
Tested:
- Handles overlap. For example, asking for lines 1, 2 & 4 prints lines 1, 2, 3, 4, 5 & 6.
- Handles end of file. For example, asking for line 15 of a file with 16 lines prints lines 15 and 16 (and doesn't give an error for the missing line 17).
Features:
- Efficient. Only looks at one element of @line_nums per line of the input file.
- Efficient. Stops reading the input file if there are no more lines to print.
Limitations:
- Assumes @line_nums is sorted. This assumption is easy to remove.
To do:
- Read the line numbers one at a time, instead of having them all in memory.