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

I Search for "Blank_Line_Separated" Records with the following script. I would now like to Sub-Search the Matched Records for records containing lines which start with "<WhatEver>" I have been trying foreach loops but not getting the results I expected.
#!/usr/bin/perl #<"Search.pl"> Split File $LOGIN=$ENV{"LOGNAME"}; system("mkdir /tmp/${LOGIN} 2>/dev/null"); $STATUS="/tmp/${LOGIN}/STATUS"; undef $/; if ( $#ARGV == 1 ) { $OPTION=$ARGV[0]; $SEARCH=$ARGV[1]; $spid = open(SFILE, ">>$STATUS") or die "STATUS File Not Found: $!\n +"; @finfo=split(/\n\n/, <STDIN>); $tRecsInfo = @finfo; } elsif ( $#ARGV == 2 ) { $OPTION=$ARGV[0]; $SEARCH=$ARGV[1]; $FLNAME=$ARGV[2]; $fpid = open(XFILE, $FLNAME) or die "Search File Not Found: $!\n"; $spid = open(SFILE, ">$STATUS") or die "Status File Not Found: $!\n" +; @finfo=split(/\n\n/, <XFILE>); $tRecsInfo = @finfo; } else { print ("Usage: $0 <with|not> <SearchString> [<File2Search>STDIN if mis +sing]\n"); exit; } @MATCHING = (); if ( $OPTION eq "with" ) { @MATCHING = grep /$SEARCH/i, @finfo; } else { @MATCHING = grep !/$SEARCH/i, @finfo; } $tMATCHING = @MATCHING; print SFILE "\n$OPTION, $SEARCH, $FLNAME"; print SFILE "\nI read ", $tRecsInfo, " RECORDS,"; print SFILE " I Selected ", $tMATCHING, " RECORDS\n"; print join "\n\n", @MATCHING; print "\n"; close(SFILE); $spid = open(SFILE, "<$STATUS" ) or die "The Status File Not Found: $! +\n"; print STDERR <SFILE>; close(SFILE);
All help appreciated muchly

Replies are listed 'Best First'.
Re: SubSearch - "Line starts with"
by roboticus (Chancellor) on Mar 31, 2010 at 14:26 UTC

    Saved:

    You really ought to make your question a bit more complete and concise (see How To Ask Questions The Smart Way and I know what I mean. Why don't you?). And you really should use strict; and use warnings; in your code (though I don't know if they'll tell you anything useful in this case ... it's just a good habit to get into).

    Anyway, my suggestion is to set the record delimiter to a blank line so each read will get one record. Then you can structure your code a bit more like:

    my ($cnt_rex, $cnt_match) = (0, 0); while (<XFILE>) { ++$cnt_rex; next unless /$SEARCH/i; ++$cnt_match; #.... do your processing here .... }

    ...roboticus

Re: SubSearch - "Line starts with"
by jethro (Monsignor) on Mar 31, 2010 at 15:11 UTC

    if the string $SEARCH has any regex special characters in it (like . or * or ()) they will match something unexpected (expect if that is what you want). You can use the function quotemeta() to escape any potential special characters in a string:

    $SEARCH= quotemeta($SEARCH);

    To anchor a regex to the start of a string you have to start it with ^:

    @MATCHING = grep /^$SEARCH/i, @finfo;

    But to anchor a regex to the start of a line(!) in a string you have to add a m flag to the regex so that perl knows it is a multiline string (and interprets ^ differently):

    @MATCHING = grep /^$SEARCH/im, @finfo;

    PS: Dividing a file on empty lines is not what I would call "searching". That did confuse me a bit when I tried to make sense of your question