On Mon, Jun 16, 2003 at 09:05:40PM -0700, Bryan Harris wrote:
>
> I'm writing a program ("showme") similar to grep, where the user
> sends data and a pattern (possibly spanning multiple lines), and
> the script tells what file the pattern is found in, and what it
> found. Very simple.
If it weren't for the "multiple lines", this really would be simple.
#!/usr/bin/perl
my $showme = shift
or die "Usage: $0 <PATTERN> [FILES]\n";
while (<>) {
print "$ARGV: $1\n" while /($showme)/gi
}
__END__
The "magic" ARGV filehandle will take care of opening and
closing the files (or reading from STDIN) and does a good
enough job of error-reporting.
And the related $ARGV variable will always tell you the name
of the "current" file.
> The problem is reading either out of a pipe or out of files.
> The following is what I'd like it to output:
I prefer to think of the problem as "multi-line matching" :-)
> Assuming:
> mytestfile: blah1\ndog\ncat\nblah2\n
> mytestfile2: blah3\ncow\n
>
> % showme
> showme <pattern> [filenames]
> - displays pattern matches in files
>
> % showme 'h\d' mytestfile*
> mytestfile: h1
> mytestfile: h2
> mytestfile2: h3
>
> % echo "blah4" | showme
> h4
Okay, a bit more complicated, but I think I'd still use <> to
handle all the reading and opening-of-files.
There are two tricks that make it easier:
#!/usr/bin/perl
my $showme = shift
or die "Usage: $0 <PATTERN> [FILES]\n";
while (defined(my $line = <>)) {
$_ .= $line;
next unless eof; # [1]
my $prefix = ($ARGV eq '-')? '' : "$ARGV: "; # [2]
print "${prefix}$1\n" while /($showme)/mgi;
$_ = '';
}
__END__
[1] eof() tells us whether we're at the end of the current file.
Instead of slurping, we're going to take each line and
concatenate it with $_, so unless we're at EOF, just keep
reading.
[2] $ARGV is the current file name, but it will be '-' if <> is
reading from STDIN.
So we'll use that fact to produce a different prefix depending
on whether we're reading from a list of files or from STDIN.
HTH
--
Steve
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]