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

I have something like
open(FILE, "$filename") or die "Cant open $filename\n"; local $/ = undef; my $lines = <FILE>; close(FILE);
which gives me the whole file in $lines. Now I need to get all lines that satisfy a pattern in $myPattern into an array @patternMatchArray Is there a way to do this quickly other than a line by line approach.

Replies are listed 'Best First'.
Re: matching lines in multi-line string
by edan (Curate) on Nov 27, 2003 at 12:23 UTC

    Don't slurp (well, 'slurp' into an array, not a scalar):

    open(FILE, "$filename") or die "Cant open $filename\n"; my @lines = <FILE>; close(FILE); my @patternMatchArray = grep { /$myPattern/ } @lines;

    If you don't need all the lines, only the ones that match, you could do it in one shot with:

    open(FILE, "$filename") or die "Cant open $filename\n"; my @patternMatchArray = grep { /$myPattern/ } <FILE>; close(FILE);
    --
    3dan

Re: matching lines in multi-line string
by CombatSquirrel (Hermit) on Nov 27, 2003 at 13:29 UTC
    When reading files, you should generally avoid slurping them into one scalar or array, as this could be quite memory intensive. A while-loop is almost always a better solution.
    Have a look at this and see if it works for you:
    open FILE, '<', $filename or die "Cannot open $filename: $!\n"; my @patternMatchArray; while (<FILE>) { push @patternMatchArray, $_ if /$myPattern/; } close FILE;
    Hope this helped.
    CombatSquirrel.
    Entropy is the tendency of everything going to hell.
Re: matching lines in multi-line string
by jeffa (Bishop) on Nov 27, 2003 at 15:44 UTC
    Slurping a filehandle into scalar can be very memory intensive, but for those times when slurping is a good solution, be sure to preserve the value of $/ so that you don't clobber other filehandle reads in the rest of your program. Here is a "safer" way to slurp:
    my $lines = do {local $/; <FILE>};
    Read this for more info.

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
Re: matching lines in multi-line string
by Roger (Parson) on Nov 27, 2003 at 12:19 UTC
    @patternMatchArray = $lines =~ /pattern/mg;
    Update: Just an idea on how to solve the problem, not the final solution. I forgot to mention that. ;-)

      Wrong. This will give you an array of substrings that were matched by the pattern. The requirement is to get the lines that match the pattern.

      You could change it to

      @patternMatchArray = $lines =~ /^.*pattern.*$/mg;

      But it doesn't seem like a good solution to me, though I can't put my finger on exactly why not...

      --
      3dan

        Well, doesn't this look rather like a homework question to you??? Of course I know that solution doesn't solve the problem. I was just giving him an idea of how to tackle the problem, not to give him a staight answer. I think OP is doing it that way (using slurp and regular expression) for a reason. ;-)