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]