#!/usr/bin/perl use feature ":5.10"; use warnings; use strict; show_usage() unless scalar(@ARGV); my $lines; my @queue; my $queue_size = 0; my $start_from = undef; my $request = shift @ARGV; ## SUGESTOES # - request == random for my $r (split /,/,$request) { given ($r) { when (/^(\d+)$/) { $lines->{$1} = undef; } when (/^(\d+)-(\d+)$/) { $a = $1; $b = $2; ($a,$b)=($b,$a) if $a > $b; for my $i ($a..$b) { $lines->{$i} = undef; } } when (/^(\d+)-$/) { $start_from = $1; } when (/^-(\d+)-$/) { $queue_size = $1; } } } while (<>) { $lines->{$.} = $_ if exists($lines->{$.}); $lines->{$.} = $_ if (defined($start_from) && $. >= $start_from); if ($queue_size) { push @queue, [$.,$_]; if (scalar(@queue) > $queue_size) { shift @queue; } } } for my $q (@queue) { $lines->{$q->[0]} = $q->[1]; } for my $line (sort {$a <=> $b} keys %$lines) { printf "%3d: %s", $line, $lines->{$line}; } sub show_usage { print "lines 1,4-5,9- file\n"; } =head1 NAME lines - head and tail mixed together =head1 SYNOPSIS lines 2,5-10,20- =head1 DESCRIPTION I found useful to have C and C and the middle mixed together: to have the option to retrieve some lines from a file that are not just in the top, or just in the bottom. Lines receives a list of lines, and shows those lines: =over 4 =item * A single digit specifies a specific line =item * A range C<2-5> specifies the lines in the range =item * A range without ending value C<10-> specified the lines starting at the tenth until the end of the file. =item * Finally, a negative range without ending value C<-10-> does what tail does: keeps the last 10 lines. =back The lines are printed with its number at the left. Future versions might have that disabled. =head1 SEE ALSO perl(1) =head1 AUTHOR Alberto Manuel Brandão Simões, Eambs@cpan.orgE =head1 COPYRIGHT AND LICENSE Copyright (C) 2009 by Alberto Manuel Brandão Simões =cut