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

I’m looking for some ideas as to how to implement the following: I want to search a file for a string, but then ONLY export the n-th line thereafter. I found various ways to display the searched for line and the next n such as “grep –A” does, but I don’t want to output anything BUT the nth line. TIA

Replies are listed 'Best First'.
Re: Search String - next line
by BrowserUk (Patriarch) on Nov 07, 2002 at 03:12 UTC

    As a one-liner

    perl -ne "$n = $.if /line 05/; print if $n and $. == ( $n + 4 )" numbe +red.dat
    Substitute your match criteria for /line 05/, the number after for the constant 4 and the name of your file at the end.

    As a program


    Nah! You're thinking of Simon Templar, originally played (on UKTV) by Roger Moore and later by Ian Ogilvy
Re: Search String - next line
by jdporter (Paladin) on Nov 07, 2002 at 04:46 UTC
    The solution is quite simple if you only expect to see the target pattern in the file once. Then you just look for the pattern, count n more lines, print the last of those, and bail.

    But if the pattern can appear more than once, it gets tricky, since it may be that n = 5 (say) but the pattern is seen a second time only 3 lines after the first. Then you sort of need to remember which line numbers will need to be printed out, and print them as you come to them.

    Here's my solution (tested):

    my $pattern = qr/match this string!/; my $n = 4; my @li; while(<>) { if ( @li && $. == $li[0] ) { print; shift @li; } /$pattern/ and push @li, $. + $n; }
    Of course, a clever perl programmer can condense this to a one-liner, but I figure it's better to show clearly what's really going on.
Re: Search String - next line
by FamousLongAgo (Friar) on Nov 07, 2002 at 02:54 UTC
    Naive stab:
    while (<>) { next unless /$pattern/; for (1..$n){ undef = (<>); } print; last; }
Re: Search String - next line
by PodMaster (Abbot) on Nov 07, 2002 at 09:41 UTC
    I got a flip flop one for ya
    #generator perl -le " print qq,line $_, for 1..100 " #the proggie (prints the 6th line after /line 1/ is detected perl -ne " /line 1/ .. $a++ == 6 && print " # sample run perl -le " print qq,line $_, for 1..100 " | perl -ne " /line 1/ .. $a +++ == 6 && print " #yields line 7

    ____________________________________________________
    ** The Third rule of perl club is a statement of fact: pod is sexy.

Re: Search String - next line
by dingus (Friar) on Nov 07, 2002 at 09:32 UTC
    Assuming the file is small enough to be read into memory in one chunk then you can do this with a single regex. Clearly you have to subsitute $Nth and $match with what you want.
    open (FILE '<filename'); $_ = join('',<FILE>); close (<FILE>); my ($result) = m!$match(?:.*?$/){$Nth}(.*?$/)!s; print $result;
    If you expect the match to occur multiple times then you should loop using a while (m! !sg) expression as in
    open (FILE '<filename'); $_ = join('',<FILE>); while ( m!$match(?:.*?$/){$Nth}(.*?$/)!sg) { print $1; # pos = length ($match) + length ($`); }
    In the looping case there is some ambiguity about what should happen in the event that $match also occurs in the lines that are skipped. In the code as written above we ignore any such possible matches. Careful manipulation of pos in the loop however does allow all $Nth lines after $match to be found - this is the line commented out in the above. Changing it so as to ensure that none of the skipped lines contains $match is left as an exercise for the student...

    Dingus


    Enter any 47-digit prime number to continue.