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

I have a datafile that looks like so....
TABLEROW 40 LUN 40 41943040 60:06:01:60:5C:4F:22:00:88:43:D4:39:04:F7:DD:11 20 RAID1/0 2 2 false 163840 false false true true 12 6 0 2048 false SP B true
I need to be able to grab the 2nd line down from LUN 40, now in shell this is fairly easy; grep "LUN 40" -A2 ./lunreport | tail -1 but i have not a clue how to do this in perl.

Replies are listed 'Best First'.
Re: trying to do a parse based on starting position.
by toolic (Bishop) on Feb 13, 2009 at 21:15 UTC
    Here is a brute-force way:
    use strict; use warnings; while (<>) { if (/LUN 40/) { $_ = <>; $_ = <>; print; } } __END__ 60:06:01:60:5C:4F:22:00:88:43:D4:39:04:F7:DD:11

    This may also be of interest: UNIX 'command' equivalents in Perl

Re: trying to do a parse based on starting position.
by Perlbotics (Archbishop) on Feb 13, 2009 at 21:21 UTC

    Possible solutions:

    Command line:

    perl -ne 'BEGIN { our $offset=-1 } $offset=2 if /^LUN 40\s*$/; print i +f !$offset--;' 743702.dat

    Script:

    use strict; my $trigger = -1; while (<>) { $trigger = $. + 2 if /^LUN 40\s*$/; print if $. == $trigger; }
    But doesn't work if LUN 40 re-triggers (e.g. two consecutive LUN 40 lines). That might need a list to match against (e.g. using grep).

      But doesn't work if LUN 40 re-triggers

      Since he only wants the last one (tail -1), it's easy to fix.

      my $target = 0; my $match; while (<>) { $target = $. + 2 if /^LUN 40\s*$/; $match = $_ if $. == $target; } print($match) if defined($match);
      That's easily fixed ...
      use strict; my $trigger = -1; while (<>) { $trigger = $. + 2 if $trigger != -1 && /^LUN 40\s*$/; # Changed: # print if $. == $trigger; # To: print, last if $. == $trigger && /^LUN 40\s*$/;
      The trigger is armed when and only when the trigger condition hasn't (yet) been hit... so no additional requirement as you suggested in closing :-)

      Update

      Hmmm, having read the question again (and not got as far as ikegami et al's posts which would have told me that), the OP wants only the line in question, not the line c/w all following, hence the solution is easier still...edited accordingly.

      A user level that continues to overstate my experience :-))
Re: trying to do a parse based on starting position.
by Lawliet (Curate) on Feb 13, 2009 at 21:19 UTC
    perl -e 'print `grep "LUN 40" -A2 ./lunreport | tail -1`;'

    :P

    And you didn't even know bears could type.

Re: trying to do a parse based on starting position.
by jwkrahn (Abbot) on Feb 13, 2009 at 22:45 UTC

    Another way to do it:

    my $line; while ( <> ) { if ( /LUN 40/ ) { $line = $. + 2; } if ( $line == $. ) { print; } }
Re: trying to do a parse based on starting position.
by bichonfrise74 (Vicar) on Feb 13, 2009 at 22:05 UTC
    Try this...
    perl -lane 'print "$F[0]" if ($. > 2)' test.txt
Re: trying to do a parse based on starting position.
by Bloodnok (Vicar) on Feb 14, 2009 at 11:12 UTC
    If, as it appears to be, you are parsing the output of an query on a database, why not print the column names (as well as their values) and parse on that or .... better still, adjust the query to select only the column in which you're interested ?

    A user level that continues to overstate my experience :-))