Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Reading specific lines in a file

by gurpreetsingh13 (Scribe)
on May 20, 2014 at 07:27 UTC ( [id://1086746]=perlquestion: print w/replies, xml ) Need Help??

gurpreetsingh13 has asked for the wisdom of the Perl Monks concerning the following question:

Hello monks,
Hope this is a simple thing. Tried to search but couldn't find a reasonable solution for the same.
What I want is to print line number say 60 to 70 in a file.

This will work out using sed
sed -n '60,70 p' wordlist
Simply using head,tail it will work out
tail -n +60 wordlist|head -10
Using perl $. it will work out
perl -ne 'print if $. ~~ [60..70]' wordlist
Using perl list context, it works out.
perl -e 'my @lines=`cat wordlist`;print @lines[60..70];'

What I want is any way we can eliminate that @lines array and do it in one line. Tried somethings but can't make it out. e.g.
perl -e 'print @(`cat wordlist`)[60..70];'

Or
perl -e 'print (@(`cat wordlist`))[60..70];'

But nothing works out. Would be thankful if you could help me in that.

Replies are listed 'Best First'.
Re: Reading specific lines in a file
by choroba (Cardinal) on May 20, 2014 at 08:10 UTC
    I'm not sure what you are after. Does the following meet your expectations (no array, one line)?
    perl -e '10 .. 20 and print while <>' wordlist

    Or

    perl -e 'print for (<>)[9 .. 19]' wordlist
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
      Thanks.
      Works.
      My hit-n-trial also worked out finally.
      perl -e 'print ((`cat wordlist`)[60..70]);'

        If you want to eliminate `cat wordlist`, you can use File::Slurp or do { local @ARGV='wordlist'; <> }.

Re: Reading specific lines in a file
by tobyink (Canon) on May 20, 2014 at 10:20 UTC

    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

      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> ); } }
Re: Reading specific lines in a file
by Discipulus (Canon) on May 20, 2014 at 08:34 UTC
    if you are talking about linenumber $. is for you:
    perl -ne 'print if ($. >= 10 and $. <=20 )' filename.ext

    HtH
    L*
    UPDATE: perl -ne 'print if 15 .. 17' *.pod
    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
      That's right. Tried it already using $.
      Just wanted to do something via a list context as a one-liner.
      Learning purpose you can say. Anyway, thanks a lot.
Re: Reading specific lines in a file
by Laurent_R (Canon) on May 20, 2014 at 09:12 UTC
    What about something really simple like that:
    perl -ne 'print if 60..70;' file.txt
      That's good one.
      Correct me if I'm wrong. Hope this is using $_ and not $., since a while loop is roaming around the statement with perl -n .
      So what would be the expanded form of this statement?
        as pointed by ambrus in the chat $. come in place because of flip flop operator
        If either operand of scalar ".." is a constant expression, that operan +d is considered true if it is equal (== ) to the current input line n +umber (the $. variable).

        HtH
        L*
        There are no rules, there are no thumbs..
        Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
        It is using implicitly both $. and $_. A possible expanded form could be:
        perl -ne 'print $_ if $. >= 60 and $. <= 70' file.txt
        or, expanding further:
        perl -e 'while (<>) {print $_ if $. >= 60 and $. <= 70;}' file.txt
Re: Reading specific lines in a file
by Anonymous Monk on May 20, 2014 at 09:31 UTC
    use Path::Tiny qw/ path /; print( (path('wordlist')->lines)[60..70] );
Re: Reading specific lines in a file
by sundialsvc4 (Abbot) on May 20, 2014 at 16:45 UTC

    This will do it, and do it efficiently:

    perl -ne 'while(<>) { next if $. < 60; last if $. > 70; print; }' wordlist

    The logic’s clear enough and it fits on one line (although I word-wrapped it for clarity):   loop if we’re not at the right starting position, break out of the loop if we’re past it, otherwise print a line.   Virtually no memory is consumed and the loop does not read the whole file.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1086746]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (4)
As of 2024-04-25 13:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found