Skip to content

Commit c8baa0c

Browse files
authored
grep: shortcut exit path for -q
* -q flag of grep is concerned if a match was found in any file * The program can terminate after the first match without searching in subsequent files * GNU grep behaves in this way; strace on my Linux system confirms that only the 1st file in argument list is opened when that file contains a match %strace grep -q perl ar awk 2> trace # gnu grep %grep open trace ... openat(AT_FDCWD, "ar", _RDONLY|O_NOCTTY|O_LARGEFILE) = 3 ^^^ final openat() in process
1 parent 0c8e2af commit c8baa0c

File tree

1 file changed

+7
-5
lines changed

1 file changed

+7
-5
lines changed

bin/grep

+7-5
Original file line numberDiff line numberDiff line change
@@ -383,21 +383,23 @@ FILE: while ( defined( $file = shift(@_) ) ) {
383383
next LINE unless $Matches;
384384

385385
$total += $Matches;
386+
last FILE if $opt->{'q'}; # single match for all files
386387

387388
if ( $opt->{p} || $opt->{P} ) {
388389
s/\n{2,}$/\n/ if $opt->{p};
389390
chomp if $opt->{P};
390391
}
391-
392-
print("$name\n"), next FILE if $opt->{l};
393-
my $showmatch = !$opt->{'q'} && !$opt->{'c'};
394-
if ($showmatch) {
392+
if ($opt->{'l'}) {
393+
print $name, "\n";
394+
next FILE;
395+
}
396+
unless ($opt->{'c'}) {
395397
print($name, ':') if $Mult;
396398
print $opt->{n} ? "$.:" : "", $_,
397399
( $opt->{p} || $opt->{P} ) && ( '-' x 20 ) . "\n";
398400
}
399401

400-
next FILE if (!$opt->{'c'} && $opt->{'1'} || $opt->{'q'}); # single match
402+
next FILE if $opt->{'1'}; # single match per file
401403
}
402404
}
403405
continue {

0 commit comments

Comments
 (0)