#!/usr/bin/perl -w package File::Grep; use strict; use Carp; BEGIN { use Exporter (); use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); $VERSION = sprintf( "%d.%02d", q(0.01) =~ /\s(\d+)\.(\d+)/ ); @ISA = qw(Exporter); @EXPORT = qw(); @EXPORT_OK = qw( fgrep ); %EXPORT_TAGS = ( ); } sub fgrep (&@) { my ( $coderef, @files ) = @_; my $returntype; if ( wantarray ) { $returntype = 2; # Return everything } elsif ( defined( wantarray ) ) { $returntype = 1; # Return just the count } else { $returntype = 0; # Return at first match } my @matches; my $count; foreach my $file ( @files ) { if ( $returntype == 2 ) { push @matches, { filename => $file, count => 0, matches => [] }; } open FILE, "<$file" or carp "Cannot open file $file to grep: $!" and next; while ( my $line = <FILE> ) { local $_ = $line; if ( &$coderef ) { $count++; last if ( $returntype == 0 ); # Last of while loop! if ( $returntype == 2 ) { $matches[-1]->{ count }++; push @{ $matches[-1]->{ matches } }, $line; } } } close FILE; if ( !$returntype && $count ) { return 1; } } if ( $returntype == 2 ) { return @matches; } elsif ( $returntype == 1 ) { return $count; } else { return 0; # Void context; if here, nothing was found, e +ver } } 1; __END__ =head1 NAME File::Grep - Find matches to a pattern in a series of files =head1 SYNOPSIS use File::Grep qw( fgrep ); # Void context if ( fgrep { /$user/ } "/etc/passwd" ) { do_something(); } # Scalar context print "The index page was hit ", fgrep { /index\.html/ } glob "/var/log/httpd/access.log.*", " times\n"; # Array context my @matches = fgrep { /index\.html } glob "/var/log/httpd/access.log +.*"; foreach my $matchset ( @matches ) { print "There were ", $matchset->{ count }, " matches in ", $matchset->{ filename }, "\n"; } =head1 DESCRIPTION File::Grep mimics the functionality of the grep function in perl, but applying it to files instead of a list. This is similar in nature to the UNIX grep command, but more powerful as the pattern can be any leg +al perl function. While looking for patterns for files is trivally easy, File::Grep take +s steps to be efficient in both computation and resources. Namely, if c +alled in void context, it will short circuit execution when a match is locat +ed and immediately report truthfulness. In scalar context, it will only +keep track of the number of matches and return that value. In array contex +t, it will generate an array of hashes that include details on the matching +-- specifically for each hash, key "filename" will be the name of the cur +rent file, "count" will be the number of hits, and "matches" will be an arr +ay reference containing the matched lines, in order of discovery. The ordering of this array will follow the same order of files as passed i +n from fgrep. The syntax for this command is similar to grep: fgrep BLOCK ARRAY. The block should be a subroutine that returns if a match was found or +not. The variable $_ will be localized before this routine is called, so ma +y be used to process the current line. Note, however, that only the original content of the line is saved in the array of hashes in array context. The array is a list of files to be grepped. If a file canno +t be opened, a warning will be issued, though the function will continue + to process remaining files; in addition, an entry in the array of hashes +will still be created as to not mess up any indexing with the original file + list. =head1 EXPORT "fgrep" may be exported, but this is not set by default. =head1 AUTHOR Michael K. Neylon, E<lt>mneylon-pm@masemware.comE<gt> =head1 SEE ALSO L<perl>. =cut
In reply to File::Grep by Masem
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |