Skip to content

Commit 5c98325

Browse files
authored
grep: implement -x for fixed strings
* Standards document mentions that option -x should work with fixed strings [1] * This version didn't allow -x with -F; add it now for better compliance with standard * I have a small test file with some C code * test1: "perl grep int a.c" --> matches "int\n" and "printf(...);\n" * test2: "perl grep -i Int a.c" --> same match as test1 * test3: "perl grep -iv Int a.c" --> matches all except "int\n" and "printf(...);\n" * test4: "perl grep -v Int a.c" --> matches all lines because Int doesn't appear at all * test5: "perl grep -F -x int a.c" --> matches only "int\n" * test6: "perl grep -Fxi Int a.c" --> same match as test5 * test7: "perl grep -Fxiv Int a.c" --> matches all except "int\n" * test8: "perl grep -Fxv Int a.c" --> matches all lines because Int doesn't appear at all 1. https://pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html
1 parent b6a4dcf commit 5c98325

File tree

1 file changed

+19
-8
lines changed

1 file changed

+19
-8
lines changed

bin/grep

+19-8
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ use File::Basename qw(basename);
5353
use File::Spec;
5454
use Getopt::Std;
5555

56-
our $VERSION = '1.002';
56+
our $VERSION = '1.003';
5757

5858
$| = 1; # autoflush output
5959

@@ -199,15 +199,26 @@ sub parse_args {
199199
}
200200

201201
if ($no_re) {
202-
if ($opt{'w'} || $opt{'x'} || $opt{'H'} || $opt{'u'}) {
203-
die("$Me: -H, -u, -w and -x are incompatible with -F\n");
202+
if ($opt{'H'} || $opt{'u'} || $opt{'w'}) {
203+
die "$Me: -H, -u and -w are incompatible with -F\n";
204204
}
205-
my $testop = $opt{'v'} ? '==' : '!=';
206-
if ($opt{'i'}) {
207-
$match_code = "for my \$pat (\@patterns) { \$Matches++ if (index(lc \$_, lc \$pat) $testop -1) }";
205+
if ($opt{'x'}) { # exact match
206+
my $testop = $opt{'v'} ? 'ne' : 'eq';
207+
if ($opt{'i'}) {
208+
$match_code = "my \$c=\$_; chomp \$c; for my \$pat (\@patterns) {\$Matches++ if (lc(\$c) $testop lc(\$pat)) }";
209+
}
210+
else { # case sensitive
211+
$match_code = "my \$c=\$_; chomp \$c; for my \$pat (\@patterns) {\$Matches++ if (\$c $testop \$pat) }";
212+
}
208213
}
209-
else { # case sensitive
210-
$match_code = "for my \$pat (\@patterns) { \$Matches++ if (index(\$_, \$pat) $testop -1) }";
214+
else { # regular match
215+
my $testop = $opt{'v'} ? '==' : '!=';
216+
if ($opt{'i'}) {
217+
$match_code = "for my \$pat (\@patterns) { \$Matches++ if (index(lc \$_, lc \$pat) $testop -1) }";
218+
}
219+
else { # case sensitive
220+
$match_code = "for my \$pat (\@patterns) { \$Matches++ if (index(\$_, \$pat) $testop -1) }";
221+
}
211222
}
212223
$matcher = eval "sub { $match_code }";
213224
die if $@;

0 commit comments

Comments
 (0)