[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#70540: grep -c -r | grep -v ':0$'
From: |
Dale R. Worley |
Subject: |
bug#70540: grep -c -r | grep -v ':0$' |
Date: |
Sun, 28 Apr 2024 18:44:45 -0400 |
For everyone's critique, here are my changes (to grep 3.11):
diff -u doc/grep.in.1.orig doc/grep.in.1
--- doc/grep.in.1.orig 2024-04-28 18:04:37.494096472 -0400
+++ doc/grep.in.1 2024-04-28 18:24:15.187984393 -0400
@@ -2,7 +2,7 @@
.de dT
.ds Dt \\$2
..
-.dT Time-stamp: "2019-12-29"
+.dT Time-stamp: "2024-04-28"
.\" Update the above date whenever a change to either this file or
.\" grep.c's 'usage' function results in a nontrivial change to the man page.
.\" In Emacs, you can update the date by running 'M-x time-stamp'
@@ -292,6 +292,9 @@
With the
.BR \-v ", " \-\^\-invert\-match
option (see above), count non-matching lines.
+With the
+.BR \-l ", " \-\^\-files\-with\-matches
+option (see below), only files with non-zero counts are listed.
.TP
.BR \-\^\-color [ =\fIWHEN\fP "], " \-\^\-colour [ =\fIWHEN\fP ]
Surround the matched (non-empty) strings, matching lines, context lines,
diff -u doc/grep.texi.orig doc/grep.texi
--- doc/grep.texi.orig 2024-04-28 18:04:40.302091195 -0400
+++ doc/grep.texi 2024-04-28 18:17:22.567712036 -0400
@@ -301,6 +301,10 @@
With the @option{-v} (@option{--invert-match}) option,
count non-matching lines.
(@option{-c} is specified by POSIX.)
+With the @option{-l} (@option{--files-with-matches}) option,
+only files with non-zero counts are listed.
+(The combination of @option{-c} and @option{-l} is not specified by
+POSIX.)
@item --color[=@var{WHEN}]
@itemx --colour[=@var{WHEN}]
diff -u src/grep.c.orig src/grep.c
--- src/grep.c.orig 2023-04-10 20:20:47.000000000 -0400
+++ src/grep.c 2024-04-28 17:57:22.527913936 -0400
@@ -1084,6 +1084,8 @@
static intmax_t out_before; /* Lines of leading context. */
static intmax_t out_after; /* Lines of trailing context. */
static bool count_matches; /* Count matching lines. */
+static bool count_matches_nonzero; /* Count matching lines; only
+ report files with matches. */
static intmax_t max_count; /* Max number of selected
lines from an input file. */
static bool line_buffered; /* Use line buffering. */
@@ -1914,17 +1916,20 @@
count = grep (desc, &st, &ineof);
if (count_matches)
{
- if (out_file)
- {
- print_filename ();
- if (filename_mask)
- print_sep (SEP_CHAR_SELECTED);
- else
- putchar_errno (0);
- }
- printf_errno ("%" PRIdMAX "\n", count);
- if (line_buffered)
- fflush_errno ();
+ if (!(count_matches_nonzero && count == 0))
+ {
+ if (out_file)
+ {
+ print_filename ();
+ if (filename_mask)
+ print_sep (SEP_CHAR_SELECTED);
+ else
+ putchar_errno (0);
+ }
+ printf_errno ("%" PRIdMAX "\n", count);
+ if (line_buffered)
+ fflush_errno ();
+ }
}
status = !count;
@@ -2891,9 +2896,16 @@
}
/* POSIX says -c, -l and -q are mutually exclusive. In this
- implementation, -q overrides -l and -L, which in turn override -c. */
+ implementation, -q overrides -l and -L. -L in turn overrides -c,
+ but -l is compatible with -c because this implementation uses
+ that combination to specify listing only non-zero counts. */
if (exit_on_match | dev_null_output)
list_files = LISTFILES_NONE;
+ if (count_matches && list_files == LISTFILES_MATCHING)
+ {
+ count_matches_nonzero = true;
+ list_files = LISTFILES_NONE;
+ }
if ((exit_on_match | dev_null_output) || list_files != LISTFILES_NONE)
{
count_matches = false;
diff -u tests/in-eq-out-infloop.orig tests/in-eq-out-infloop
--- tests/in-eq-out-infloop.orig 2024-04-28 18:32:29.435077799 -0400
+++ tests/in-eq-out-infloop 2024-04-28 17:56:59.254957675 -0400
@@ -29,7 +29,7 @@
compare err.exp err || fail=1
# But with each of the following options it must not exit-2.
- for i in -q -m1 -l -L; do
+ for i in -q -m1 -l -L -c; do
timeout 10 grep $i 0 $arg < out >> out 2> err; st=$?
test $st = 2 && fail=1
done
diff -u tests/options.orig tests/options
--- tests/options.orig 2024-04-28 18:33:47.645931404 -0400
+++ tests/options 2024-04-28 18:00:23.701573443 -0400
@@ -12,6 +12,9 @@
# grep [ -E| -F][ -c| -l| -q ][-insvx][-e pattern_list]
# -f pattern_file ... [file ...]
# grep [ -E| -F][ -c| -l| -q ][-insvx] pattern_list [file...]
+#
+# Also checks that the option combination "-c -l" only reports files
+# with non-zero counts.
. "${srcdir=.}/init.sh"; path_prepend_ ../src
@@ -46,4 +49,63 @@
fail=1
fi
+# check the option combination -c -l
+echo 'This file contains foo.' > options.in.foo
+echo 'This file contains bar.' > options.in.bar
+
+# check without options
+output=$( grep foo options.in.* > /dev/null 2>&1 )
+if test $? -ne 0 ; then
+ echo "Options: Wrong status code, test #5a failed"
+ fail=1
+fi
+if test "$output" -ne "options.in.foo:This file contains foo." ; then
+ echo "Options: Wrong output, test #5a failed: $output"
+ fail=1
+fi
+
+# check with -c
+output=$( grep -c foo options.in.* > /dev/null 2>&1 )
+if test $? -ne 0 ; then
+ echo "Options: Wrong status code, test #5b failed"
+ fail=1
+fi
+if test "$output" -ne "options.in.foo:1 options.in.bar:0" ; then
+ echo "Options: Wrong output, test #5b failed: $output"
+ fail=1
+fi
+
+# check with -l
+output=$( grep -l foo options.in.* > /dev/null 2>&1 )
+if test $? -ne 0 ; then
+ echo "Options: Wrong status code, test #5c failed"
+ fail=1
+fi
+if test "$output" -ne "options.in.foo" ; then
+ echo "Options: Wrong output, test #5c failed: $output"
+ fail=1
+fi
+
+# check with -c -l
+output=$( grep -c -l foo options.in.* > /dev/null 2>&1 )
+if test $? -ne 0 ; then
+ echo "Options: Wrong status code, test #5d failed"
+ fail=1
+fi
+if test "$output" -ne "options.in.foo:1" ; then
+ echo "Options: Wrong output, test #5d failed: $output"
+ fail=1
+fi
+
+# check with -v -c -l
+output=$( grep -v -c -l foo options.in.* > /dev/null 2>&1 )
+if test $? -ne 0 ; then
+ echo "Options: Wrong status code, test #5e failed"
+ fail=1
+fi
+if test "$output" -ne "options.in.bar:1" ; then
+ echo "Options: Wrong output, test #5e failed: $output"
+ fail=1
+fi
+
Exit $fail