Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Reading nth line from a file

by perlthirst (Scribe)
on Dec 19, 2008 at 05:22 UTC ( #731453=perlquestion: print w/ replies, xml ) Need Help??
perlthirst has asked for the wisdom of the Perl Monks concerning the following question:

I am having one program, which read a line by line from a file, if the line matches for the particular pattern, then i should read nth line from a current line.

some simple example is:

open(FH,"test.txt"); while ( <FH> ) { ## If the line matches for this pattern, I should read 4th lin +e from current line if ( $_ =~/you have to read the fourth line/ ){ $i=0; while ($i<4) { $line = <FH>; $i++; } print $line; } ## If the line matches for this pattern, I should read 2nd lin +e from current line elsif ( $_ =~/you have to read the second line/ ){ $i=0; while ($i<2) { $line = <FH>; $i++; } print $line; } }

Input:
first line
second line
third line
you have to read the fourth line
one
two
three
four
five
six
you have to read the second line
one
two
three

output:
four
two

The above coding works for me for my requirement

but i felt that the way that i have handled to read nth line from a file, is inefficient.. kindly advice some efficient way to do the above.

Comment on Reading nth line from a file
Download Code
Re: Reading nth line from a file
by jwkrahn (Monsignor) on Dec 19, 2008 at 05:53 UTC
    $ echo "first line second line third line you have to read the fourth line one two three four five six you have to read the second line one two three" | perl -e' my %lookup = qw/ fourth 4 second 2 /; while ( <> ) { if ( /you have to read the (\w+) line/ && exists $lookup{ $1 } ) { $lines{ $. + $lookup{ $1 } }++; } if ( $lines{ $. } ) { print; } } ' four two
Re: Reading nth line from a file
by brsaravan (Scribe) on Dec 19, 2008 at 06:15 UTC
    Here is another simple way.
    my @arrvar = <FH>; map { if ($arrvar[$_] =~ /you have to read the fourth line/) { print "$arrvar[$_+4]"; } elsif ($arrvar[$_] =~ /you have to read the second line/) { print "$arrvar[$_+2]"; } }0..$#arrvar;

      Thanks for your reply.

      But reading the whole file into an array may not be efficient. If the file size is too large, it will take so much memory i think.

Re: Reading nth line from a file
by NetWallah (Abbot) on Dec 19, 2008 at 06:32 UTC
    Something extensible .. more coding efficient, but not necessarily less execution time ...
    use strict; my %actionlist=( "you have to read the fourth line" => 4, "you have to read the second line" => 2 ); my $re = "(" . join ("|", keys %actionlist) . ")"; $re= qr|$re|; my $printthis = -1; while (<DATA>){ if (my ($match) = /$re/){ $printthis = $actionlist{$match}; } $printthis-- == 0 and print; } __DATA__ first line second line third line you have to read the fourth line one two three four five six you have to read the second line one two three
    Update: On reflection, this solution is very similar to jwkrahn's.

         ..to maintain is to slowly feel your soul, sanity and sentience ebb away as you become one with the Evil.

Re: Reading nth line from a file
by imrags (Monk) on Dec 19, 2008 at 07:25 UTC
    Use "$." to keep a tab on you line number.
    It's better than looping thru the whole file.
    Else
    you can use a counter which increments after each line.
    Raghu
Re: Reading nth line from a file
by Bloodnok (Vicar) on Dec 19, 2008 at 12:47 UTC
    Methinx recipe 8.8 Reading a Particular Line in a File, from the perl Cookbook would be of use to you.

    Update

    Ooops, my apologies to O'Reilly ... seemingly genuine URL removed - apparently referenced an unauthorised Ukrainian website - many thanx to Narveson.

    A user level that continues to overstate my experience :-))
Reaped: Re: Reading nth line from a file
by NodeReaper (Curate) on Dec 19, 2008 at 18:17 UTC
Re: Reading nth line from a file
by gmontema (Initiate) on Dec 19, 2008 at 18:41 UTC

    open(FH,"test.txt");
    $i=0;
    $j1=0;
    $j2=0;
    while ( <FH> ) {

            ## If the line matches for this pattern, I should read 4th line from current line
            if ( $_ =~/you have to read the fourth line/ ){
                    $j1=-4;
            }
            elsif ( $j1<0 ){
                    $j1++;
                    print $_ if $j1==0;
            }
            ## If the line matches for this pattern, I should read 2nd line from current line
            elsif ( $_ =~/you have to read the second line/ ){
                    $j2=-2;
            }
            elsif ( $j2<0 ){
                    $j2++;
                    print $_ if $j2==0;
            }
    print $i++,"\n";


      sorry disregard the previous message.

        open(FH,"test.txt");
        my $i=0;
        my @p =();
        while ( <FH> ) {
                ## If the line matches for this pattern, I should read 4th line from current line
                if ( $_ =~/you have to read the fourth line/ ){
                        push @p,$i+4;
                }
                ## If the line matches for this pattern, I should read 2nd line from current line
                elsif ( $_ =~/you have to read the second line/ ){
                        push @p,$i+2;
                }
                @p=sort(@p);
                foreach my $j(@p){print $_ if $j==$i; shift @p if $j<=$i;} 
        $i++;


        Input:
        first line 1
        second line 2
        third line 3
        you have to read the fourth line
        one 5
        two
        three 7
        four
        five 9
        six 6
        you have to read the second line
        one 12
        two
        three 13
        first line 14
        second line 15
        third line 16
        you have to read the fourth line
        you have to read the second line
        one 20
        two with in a four
        four with two inside
        five 23
        six 24
        three 25
        you have to read the second line
        you have to read the fourth line
        two with a for
        two 29
        three 30
        four in a two
        ten 32
        one 33

        Output:
        four
        two
        two with in a four
        four with two inside
        two with a for
        four in a two

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://731453]
Approved by xdg
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (6)
As of 2014-12-20 01:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (94 votes), past polls