[ale] Perl Question

Fletch fletch at phydeaux.org
Mon Oct 16 21:49:25 EDT 2000



  > #!/usr/bin/perl
  > open (IN "</my/path/to/file")||die "$!\n";
  > @stuff=<IN>;
  > chomp (@stuff);

        If you're just printing the lines back out again, it makes
more sense not to chomp them all.  And for really large files, using 
`@a = <FH>' to read the entire file in can gobble up large amounts of
RAM (i.e. you wouldn't want to parse huge logs on a production machine 
during the day with something like this :).


  > # Now for the fun part
  > # it's clunky, but it works
  > 
  > for ($i=0;$i<=$#stuff;$i++){
  > 	if ($stuff[$i] =~ m/pattern/){push (@found, $i)}
  > }

        Written like a C programmer. :)  A more idiomatic way would
be something like:


foreach( 0 .. $#stuff ) {
  push @found, $_ if $stuff[$_] =~ /pattern/
}


        or even more succinctly:


@found = grep { $stuff[$_] =~ /pattern/ } 0 .. $#stuff;


  > #now you have an array of numbers corresponding to the array elements
  > #that match your pattern.
  > 
  > foreach $found (@found){
  > 	print "$found[$found-1]\n$found[$found]\n$found[$found+1]";
  > }

        Again, if you don't chomp this simply becomes:


print @found[ $_-1 .. $_+1 ] foreach @found;


        But then you've still got a fencepost error if the first line
matches and will get @found[ -1, 0, 1 ] which will print the last line 
before the first and second lines.  You'd really want something along
the lines of:


print @found[ ($_-1 < 0 ? 0 : $_-1) .. $_+1 ] foreach @found;


        And of course as you said, TMTOWTDI.

-- 
Fletch                | "If you find my answers frightening,       __`'/|
fletch at phydeaux.org   |  Vincent, you should cease askin'          \ o.O'
678 443-6239(w)       |  scary questions." -- Jules                =(___)=
                      |                                               U
--
To unsubscribe: mail majordomo at ale.org with "unsubscribe ale" in message body.





More information about the Ale mailing list