in reply to Reading specific lines in a file

Note that although many of them are elegant, all the techniques posted so far will read the entire input file. If you only need lines 60 to 70 out of a million line file, this is fairly wasteful.

The following example actually stops reading the file after the 70th line has been encountered:

perl -ne '$.<60 ? next : $.>70 ? last : print' wordlist.txt

If you actually need these lines in an array for some reason, you can do something like this:

perl -ne '$.<60 ? next : $.>70 ? last : push @arr, $_ }END{ print scal +ar(@arr),"\n"' wordlist.txt
use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name

Replies are listed 'Best First'.
Re^2: Reading specific lines in a file ( Path::Tiny::lines patch)
by Anonymous Monk on May 20, 2014 at 10:47 UTC

    Note that although many of them are elegant, all the techniques posted so far will read the entire input file.

    :) Path::Tiny::lines patch

    use Path::Tiny qw/ path /; print path( 'wordlist' )->lines( { range => [ 60, 70] } ); sub Path::Tiny::lines { package Path::Tiny; my $self = shift; my $args = _get_args( shift, qw/binmode chomp count range/ ); my $binmode = $args->{binmode}; $binmode = ( ( caller(0) )[10] || {} )->{'open<'} unless defined $ +binmode; my $fh = $self->filehandle( { locked => 1 }, "<", $binmode ); my $chomp = $args->{chomp}; # XXX more efficient to read @lines then chomp(@lines) vs map? if( my $count = $args->{count} ){ ## count trumps/clobbes range $args->{range} = [ 0, $count ]; } if( my @range = @{ $args->{range} || [] } ){ my( $start, $end ) = @range; $start ||= 0; defined $end or $end = -1; my @result; local $.; while ( my $line = <$fh> ) { next if $. < $start; $line =~ s/(?:\x{0d}?\x{0a}|\x{0d})$// if $chomp; push @result, $line ; last if $. >= $end; } return @result; } elsif ($chomp) { return map { s/(?:\x{0d}?\x{0a}|\x{0d})$//; $_ } <$fh>; ## no +critic } else { return wantarray ? <$fh> : ( my $count =()= <$fh> ); } }