aboutsummaryrefslogtreecommitdiff
path: root/bsgrep
diff options
context:
space:
mode:
Diffstat (limited to 'bsgrep')
-rwxr-xr-xbsgrep91
1 files changed, 65 insertions, 26 deletions
diff --git a/bsgrep b/bsgrep
index ff98f07..6521d58 100755
--- a/bsgrep
+++ b/bsgrep
@@ -28,16 +28,29 @@ $SIG{__WARN__} = sub {
print STDERR $m unless $opt{s};
};
-sub grep_usage {
- print "usage: $self [--help | --version | -[Fhiklnrsvwqz] [-d char] ...] <regex> [<file> ...]\n";
-}
-
sub grep_options {
- getopts('d:Fhiklnqrsvwz', \%opt) || exit 1;
- if($opt{h}) {
- grep_usage();
- exit(0);
+ my @nargv;
+ my $was_e;
+
+ # first, grab all the -e options and remove them from @ARGV,
+ # because Getopt::Std doesn't support multiple occurrences of
+ # a flag with different args. probably it would be better to
+ # use Getopt::Long, but for now this works.
+ for(@ARGV) {
+ if($was_e) {
+ push @patterns, $_;
+ $was_e = 0;
+ } elsif($_ eq '-e') {
+ $was_e = 1;
+ } elsif($_ =~ /-e(.*)/) {
+ push @patterns, $1;
+ } else {
+ push @nargv, $_;
+ }
}
+ @ARGV = @nargv;
+
+ getopts('d:FhiklnNqrsvwz', \%opt) || exit 1;
}
sub print_line {
@@ -58,17 +71,31 @@ sub join_options {
}
sub handle_line {
- local $_ = $_[0];
+ my $match = 0;
+
+ for my $pat (@patterns) {
+ if($opt{v}) {
+ $match++ if $out !~ /$pat/;
+ } else {
+ $match++ if $out =~ /$pat/;
+ }
+ }
+
+ return unless $match;
+
+ if($opt{N}) {
+ return unless $match == @patterns;
+ }
+
$ret = 0 if $ret == 1;
return if $opt{q};
+
if($opt{l}) {
if(!$printed{$ARGV}++) {
print "$ARGV\n";
}
- } elsif($opt{v}) {
- print_line($out) if $out !~ /$regex/;
} else {
- print_line($out) if $out =~ /$regex/;
+ print_line($out);
}
}
@@ -98,15 +125,19 @@ if(defined($ARGV[0])) {
if($self =~ /join/) {
join_options();
- $regex = '^'; # every string has a beginning...
+ push @patterns, '^'; # every string has a beginning...
} else {
grep_options();
- if(!($regex = shift)) {
- grep_usage();
- die("$self: missing required regex argument\n");
+
+ if(!@patterns) {
+ if(!($patterns[0] = shift)) {
+ grep_usage();
+ die("$self: missing required pattern argument\n");
+ }
}
- $regex = quotemeta($regex) if $opt{F};
- $regex = "(?i)$regex" if $opt{i};
+
+ map { $_ = quotemeta } @patterns if $opt{F};
+ map { $_ = "(?i)$_" } @patterns if $opt{i};
}
if($opt{r}) {
@@ -153,7 +184,7 @@ while(<>) {
$out =~ s/$cont$//;
}
} else {
- handle_line($out);
+ handle_line();
undef $out;
}
} continue {
@@ -161,7 +192,7 @@ while(<>) {
if(eof) {
if($out) {
warn "$self: $ARGV:$.: last line ends with continuation\n" unless $opt{s};
- handle_line($out);
+ handle_line();
undef $out;
}
close ARGV;
@@ -183,7 +214,7 @@ bsjoin - join lines with backslash continuation
=head1 SYNOPSIS
-bsgrep [B<[-hknwz]> B<-d> I<char> I<...>] [I<file> I<...>]
+bsgrep [B<[-hknwz]> B<-d> I<char> I<...>] [B<-e> I<pattern> ... | I<pattern>] [I<file> I<...>]
bsjoin [B<[-hiklnqrsvwz]> B<-d> I<char> I<...>] [I<file> I<...>]
@@ -235,11 +266,6 @@ For continuation lines, remove any leading whitespace. This option is
specific to B<bsgrep>. The B<grep> B<-w> option can be simulated with
the Perl B<\b> syntax in the regex.
-=item -h
-
-Prints a short help message and exits. Not compatible with B<grep>, which
-uses B<-h> for something else.
-
=item -z
Use zero bytes (ASCII NUL) rather than newlines for line terminators,
@@ -265,6 +291,12 @@ These options are only supported by B<bsgrep>:
=over 4
+=item -e I<pattern>
+
+Use I<pattern> as the pattern. May be used multiple times, in which case
+they are ORed together (a line that matches any I<pattern> is a match)... unless
+the B<-N> option is used, q.v. Same as B<grep>.
+
=item -F
Treat pattern(s) as fixed strings, not regular expression(s). Same as B<grep>.
@@ -278,6 +310,13 @@ Case-insensitive search (same as B<grep>).
Instead of printing lines that match, print only the names of files
that contain matches (same as B<grep>).
+=item -N
+
+When multiple patterns are given with multiple B<-e> options, only
+select lines that match all of the patterns; the default is to select
+lines that match any of the patterns. This option doesn't exist
+in B<grep>.
+
=item -r
Recursively read all files under each directory, following symlinks