http://qs321.pair.com?node_id=932617


in reply to Need to search for a string in a file

You needn't pull the whole file into memory just to search for one line.
The caret character,(^), means start of the line in a regex. Read perlre, these meta-characters is the second subject covered.
You can match save and exit the loop in one statement.
sub get_file_from_log(){ my $log_name=shift; open(my $log_file, "<", $log_name); my $file_name; while (<logFile>){ last if ($file_name) = /^Generated filename\s*=\s*(.+)$/; } return $file_name; }

print "Good ",qw(night morning afternoon evening)[(localtime)[2]/6]," fellow monks."

Replies are listed 'Best First'.
Re^2: Need to search for a string in a file
by jwkrahn (Abbot) on Oct 20, 2011 at 20:38 UTC
    sub get_file_from_log(){ my $log_name=shift; open(my $log_file, "<", $log_name);

    Your prototype says to accept NO arguments but your next line says to accept ONE argument.    You should not use prototypes!

    You should always verify that open worked correctly before trying to use a possibly invalid filehandle.

    open(my $log_file, "<", $log_name); my $file_name; while (<logFile>){

    You are opening the filehandle $log_file but you are trying to read from the filehandle logFile?

Re^2: Need to search for a string in a file
by akrrs7 (Acolyte) on Oct 20, 2011 at 11:51 UTC
    Hello Utilitarian...works like a charm. Thanks. I've read perlretut and perlre but still fumble. I will slowly get the hang as I keep writing code. Perl is not as intuitive to me as C++ and Java. Thanks a lot.....
      Perl is not as intuitive to me
      . You will find your way here. The terminology slightly is different, but there is always more than one way to do it in Perl, which provides extended expressibility.
Re^2: Need to search for a string in a file
by anneli (Pilgrim) on Oct 20, 2011 at 21:25 UTC

    Will my @list = grep /re/, <FH> necessarily pull the entire file into memory? (I don't know and would like to know for sure!)

    It sure seems to!

    open my $fh, "<", "/dev/urandom" or die "$!"; my @a = grep /huh, whaddayamean/, <$fh>;

      Someone please correct me if I'm wrong, but I don't think your example will pull the entire file into memory. I think it will read lines from $fh one at a time, passing them to grep, which will return matching lines to @a.

      However, you're reading from /dev/urandom, which is an endless stream of random bytes, not a file which has an end. So eventually @a is going to get very large, yes. Also, depending on what your end-of-line delimiter is set to, <$fh> may return some very long lines for grep to deal with.

        I thought (hoped) that grep would have the behaviour you described; but even when I use a very unlikely regular expression, perl's memory usage increases at a constant rate.

        The rate doesn't appear to differ depending on what regular expression I use, which seems to imply it's not the matches (of which I doubt there are any) filling memory, but just the input from /dev/urandom (which, as you mention, is endless).

        The EOL delimiter is probably \n, which should occur in /dev/urandom 1 in 256 times (so long, but not that long).