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

I need help on this one all! I have tried various ways, hash, array, seek. I need to discard all lines that match the __DISCARD__below. The rest I need to save off or print. Thank you!
use strict; use warnings; my (%map,@tmp,$line,$vhost,$next_line); open (MAP, "-|", "/usr/ios/cli/ioscli lsmap -all") or die $!; while (<MAP>) { next if $_ =~ /^$/; next if $_ =~ /--.*/; next if $_ =~ /^SVSA.?/; #push @tmp, (split(" ", $vh, 0 )); if ( /^vhost/i ) { my $pos = tell $fh; my $next_line = <$fh>; seek $fh, $pos, 0; } } __OUT__ vhost0 U9117.MMD.218A8B7-V2-C2 0x0000000 +b VTD vtscsi0 Status Available LUN 0x8100000000000000 Backing device l02duapofdev_r1.58ff94782d7c325acc49a8dd9c04bb1e Physloc Mirrored N/A vhost1 U9117.MMD.218A8B7-V2-C12 0x0000000 +3 VTD NO VIRTUAL TARGET DEVICE FOUND vhost2 U9117.MMD.218A8B7-V2-C13 0x0000000 +4 VTD NO VIRTUAL TARGET DEVICE FOUND vhost8 U9117.MMD.218A8B7-V1-C19 0x0000000 +a VTD vtscsi36 Status Available LUN 0x8100000000000000 Backing device l02dudbofqa2_a1.45b2b49e9b5d2e2a54279a67fab75306 Physloc Mirrored N/A VTD vtscsi37 Status Available LUN 0x8200000000000000 Backing device l02dudbofqa2_r1.0d0657fb7a38e5afe50956bc8fedfb2e Physloc Mirrored N/A __DISCARD__ vhost1 U9117.MMD.218A8B7-V2-C12 0x0000000 +3 VTD NO VIRTUAL TARGET DEVICE FOUND vhost2 U9117.MMD.218A8B7-V2-C13 0x0000000 +4 VTD NO VIRTUAL TARGET DEVICE FOUND

Replies are listed 'Best First'.
Re: discard lines after match
by Laurent_R (Canon) on Nov 10, 2014 at 21:49 UTC
    Hmm, not sure I really understand what your problem is, but if you just want to discard all lines after __DISCARD__ tag (including that line itself), then you just need to add this code line in your while loop:
    last if /^__DISCARD__/;
    Now, the problem is that your program isn't doing anything useful with the data being read at this point. I would assume that you want to do something with the lines you are reading and that you don't filter out with your regexes, perhaps printing them to STDOUT or to a file, or possibly storing them in an array or something else for further processing.

    In addition, just one minor comment:

    next if $_ =~ /--.*/; next if $_ =~ /^SVSA.?/;
    The .* and .? seem to be pointless here. You could have:
    next if $_ =~ /--/; next if $_ =~ /^SVSA/;
    which would yield the same results (except that this second version might probably be slightly more efficient, but that would be hardly noticeable, even with large input). This is really secondary, but it seems to indicate some misunderstandings in the comprehension of how regexes work. So, you are discarding lines matching --, presumably because -- might indicate the beginning of a comment (it does in some programming languages), but if this is the case, you should do it only if the -- comes at the beginning of the line, so that you might prefer something like this:
    next if $_ =~ /^--/;
    or possibly
    next if $_ =~ /^\s*--/; # also removing lines having -- with some lead +ing white spaces
    Similarly, discarding the "empty" lines might be better written:
    next if $_ =~ /^\s*$/; # also removing lines with only white spaces

Re: discard lines after match
by boftx (Deacon) on Nov 10, 2014 at 20:22 UTC

    Not knowing the full size of the data set this might be overkill, but...

    It looks like you can start a hash for each vhost you see, and stick the name of it in $vh or whatever. Then if you see "NO VIRTUAL" simply delete the hash and go on to the next line. In the hash itself you would collect the data elements for each VTD in its own hash. When you see the next vhost tag push the hash you just build onto an array of hashref. Once you see the end of the data ("__DISCARD__") break out of the loop and loop through the array, formating and printing or processing as desired.

    You must always remember that the primary goal is to drain the swamp even when you are hip-deep in alligators.