in reply to printing the line after grepping

If you change from the scalar context of grep to the list context, it'll capture the lines that match and then you can print out the list of matching lines.

The codes would look something like this:

open(FILE,"<",$filepath) or die "Couldn't open file for writing: $!"; @error1 = grep { /0 Items in Feed & 0 New Fetched Items/ } <FILE>; if(scalar(@error1)>0) { print "match found\n"; print "@error1"; } else { print "nothing"; } close FILE;

I tried the above snippet on a test file and it works like I believe you are hoping.

Note several things. First, I find that it is generally a good idea to use the 3-argument form of the open as I did in the above.

Second, since the code is storing the lines returned by grep into a list, it is easy to see if any lines matched simply by checking the number of entries in the list (i.e., by using if(scalar(@error)>0){...more code...}. It is, of course equally valid to use if(@error1 > 0){...more code...} since the if() forces @error1 into scalar context so that it directly returns the number of elements in it. I prefer (just my own preference) to explicitly use the scalar() function to remind me that I'm looking for the number of elements in the list.

Third, I do print "@error1" under the assumption (as reflected in my code snippet and in yours) that the lines already contain a "new line" character (i.e., "\n") at the end of each line). I make that assumption because there is no chomp() after reading in the lines (you could add chomp; into the block code in your grep before the reqex match). Given that they already contain the new line, then just doing a <c>print "@error1" will result in output that is already line separated.

Finally, I much prefer the other responders' suggestions to use while() rather than grep() so that you only read one line at a time into your space. grep(), as others wisely note, first slurps the entire file into your working space as a list and then operates on that list. Using the while() construct only works with one line at a time which is much more conservative of work space. Of course, if your FILE is not very big then the grep() may be a little more succinct and compact. But, from my perspective, that's for you to decide.

I hope this helps.

ack Albuquerque, NM

Replies are listed 'Best First'.
Re^2: printing the line after grepping
by ikegami (Patriarch) on Nov 11, 2009 at 18:04 UTC

    since the if() forces @error1 into scalar context

    No. Operators only impose context on their operands, and @error1 is not if's operand. if imposes a scalar context on > (which does nothing since > always returns a scalar).

    On the other hand, @error1 is an operand of >, and > imposes a scalar context on its operands.

    I prefer to explicitly use the scalar() function to remind me that I'm looking for the number of elements in the list.

    First of all, you're wrong about scalar returning the number of elements in a list.

    >perl -le"print join ',', 5,6,7" 5,6,7 >perl -le"print join ',', scalar(5,6,7)" 7 <--- Not 3 >perl -le"print join ',', localtime" 13,2,13,11,10,109,3,314,0 >perl -le"print join ',', scalar(localtime)" Wed Nov 11 13:02:26 2009 <--- Not 9

    Don't confuse array for list.

    I prefer to explicitly use the scalar() function to remind me that I'm looking for the number of elements in the [array].

    If that's true, you'd be better off using 0+@error1. It's much better at indicating you want a number of elements.

    But really, doesn't > 0 already indicate you're dealing with a number?!