#!/usr/bin/perl use Getopt::Std; my $opts = 'ulhIive:F:q'; getopts($opts) or usage(); my $pat = defined($opt_e) ? $opt_e : @ARGV ? shift : usage(); my $qr = $opt_i ? qr/$pat/i : qr/$pat/; my $format; if (defined $opt_F) { $format = $opt_F . "\n"; } else { my %format = (l => '%s'."\n", h => '%2$s'."\n", q => "", "" => $opt_I || @ARGV > 1 ? "%s: %s\n" : '%2$s'."\n", ); my $fk = ""; $fk .= 'l' if $opt_l; $fk .= 'h' if $opt_h; $fk .= 'q' if $opt_q; $format = $format{$fk}; unless (defined $format) { warn "Incompatible options.\n"; usage(); } } $| = 1 if $opt_u; $rc = 1; # No matches; if ($opt_I) { while () { chomp; do_file($_) } } elsif (@ARGV) { do_file($_) for @ARGV; } else { do_file(\*STDIN); } exit $rc; sub do_file { my $file = shift; my $fh; if (ref $file) { $fh = $file; $file = ""; } else { return if -d $file; unless (open $fh, "<", $file) { warn "Couldn't open '$file': $!; skipping\n"; return; } } while (<$fh>) { chomp; if (/$qr/ ^ $opt_v) { $rc = 0; # match printf $format, $file, $_, $.; return if $opt_l; } } } sub usage { print STDERR <