From 1828179ef95d256c0ac3acc45515fd433399c948 Mon Sep 17 00:00:00 2001 From: "Philip.Hazel" Date: Sun, 16 Oct 2016 16:48:14 +0000 Subject: [PATCH] Add -t to pcre2grep. --- ChangeLog | 2 ++ RunGrepTest | 24 ++++++++++++++++++++++++ doc/pcre2grep.1 | 27 ++++++++++++++++++++------- src/pcre2grep.c | 21 +++++++++++++++++++-- testdata/grepoutput | 32 ++++++++++++++++++++++++++++++++ 5 files changed, 97 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8b6401e..878f563 100644 --- a/ChangeLog +++ b/ChangeLog @@ -78,6 +78,8 @@ this situation and does not try to use JIT. (untested by me). Also, look for GREP_COLOUR or GREP_COLOR if the environment variables PCRE2GREP_COLOUR and PCRE2GREP_COLOR are not found. +14. Add the -t (grand total) option to pcre2grep. + Version 10.22 29-July-2016 -------------------------- diff --git a/RunGrepTest b/RunGrepTest index 8042531..decd548 100755 --- a/RunGrepTest +++ b/RunGrepTest @@ -568,6 +568,30 @@ echo "---------------------------- Test 112 -----------------------------" >>tes (cd $srcdir; $valgrind $vjs $pcre2grep --file-offsets -M 'match (\d+):\n (.)\n' testdata/grepinput) >>testtrygrep echo "RC=$?" >>testtrygrep +echo "---------------------------- Test 113 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep --total-count 'the' testdata/grepinput*) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 114 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -tc 'the' testdata/grepinput*) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 115 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -tlc 'the' testdata/grepinput*) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 116 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -th 'the' testdata/grepinput*) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 117 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -tch 'the' testdata/grepinput*) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 118 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $vjs $pcre2grep -tL 'the' testdata/grepinput*) >>testtrygrep +echo "RC=$?" >>testtrygrep + # Now compare the results. $cf $srcdir/testdata/grepoutput testtrygrep diff --git a/doc/pcre2grep.1 b/doc/pcre2grep.1 index b5cc1da..c3a7b3d 100644 --- a/doc/pcre2grep.1 +++ b/doc/pcre2grep.1 @@ -1,4 +1,4 @@ -.TH PCRE2GREP 1 "14 October 2016" "PCRE2 10.23" +.TH PCRE2GREP 1 "16 October 2016" "PCRE2 10.23" .SH NAME pcre2grep - a grep with Perl-compatible regular expressions. .SH SYNOPSIS @@ -180,13 +180,15 @@ This is equivalent to setting both \fB-A\fP and \fB-B\fP to the same value. .TP \fB-c\fP, \fB--count\fP Do not output lines from the files that are being scanned; instead output the -number of matches (or non-matches if \fB-v\fP is used) that would otherwise -have caused lines to be shown. By default, this count is the same as the number -of suppressed lines, but if the \fB-M\fP (multiline) option is used (without -\fB-v\fP), there may be more suppressed lines than the number of matches. +number of lines that would have been shown, either because they matched, or, if +\fB-v\fP is set, because they failed to match. By default, this count is +exactly the same as the number of suppressed lines, but if the \fB-M\fP +(multiline) option is used (without \fB-v\fP), there may be more suppressed +lines than the number of matches. .sp If no lines are selected, the number zero is output. If several files are are -being scanned, a count is output for each of them. However, if the +being scanned, a count is output for each of them and the \fB-t\fP option can +be used to cause a total to be output at the end. However, if the \fB--files-with-matches\fP option is also used, only those files whose counts are greater than zero are listed. When \fB-c\fP is used, the \fB-A\fP, \fB-B\fP, and \fB-C\fP options are ignored. @@ -573,6 +575,17 @@ Suppress error messages about non-existent or unreadable files. Such files are quietly skipped. However, the return code is still 2, even if matches were found in other files. .TP +\fB-t\fP, \fB--total-count\fP +This option is useful when scanning more than one file. If used on its own, +\fB-t\fP suppresses all output except for a grand total number of matching +lines (or non-matching lines if \fB-v\fP is used) in all the files. If \fB-t\fP +is used with \fB-c\fP, a grand total is output except when the previous output +is just one line. In other words, it is not output when just one file's count +is listed. If file names are being output, the grand total is preceded by +"TOTAL:". Otherwise, it appears as just another number. The \fB-t\fP option is +ignored when used with \fB-L\fP (list files without matches), because the grand +total would always be zero. +.TP \fB-u\fP, \fB--utf-8\fP Operate in UTF-8 mode. This option is available only if PCRE2 has been compiled with UTF-8 support. All patterns (including those for any \fB--exclude\fP and @@ -778,6 +791,6 @@ Cambridge, England. .rs .sp .nf -Last updated: 14 October 2016 +Last updated: 16 October 2016 Copyright (c) 1997-2016 University of Cambridge. .fi diff --git a/src/pcre2grep.c b/src/pcre2grep.c index fe87022..8b6399e 100644 --- a/src/pcre2grep.c +++ b/src/pcre2grep.c @@ -177,6 +177,8 @@ static int bufthird = PCRE2GREP_BUFSIZE; static int max_bufthird = PCRE2GREP_MAX_BUFSIZE; static int bufsize = 3*PCRE2GREP_BUFSIZE; static int endlinetype; +static int total_count = 0; +static int counts_printed = 0; #if defined HAVE_WINDOWS_H && HAVE_WINDOWS_H static int dee_action = dee_SKIP; @@ -218,6 +220,7 @@ static BOOL omit_zero_count = FALSE; static BOOL resource_error = FALSE; static BOOL quiet = FALSE; static BOOL show_only_matching = FALSE; +static BOOL show_total_count = FALSE; static BOOL silent = FALSE; static BOOL utf = FALSE; @@ -402,6 +405,7 @@ static option_item optionlist[] = { { OP_OP_NUMBER, 'S', &S_arg, "jeffS", "replace matched (sub)string with X" }, #endif { OP_NODATA, 's', NULL, "no-messages", "suppress error messages" }, + { OP_NODATA, 't', NULL, "total-count", "print total count of matching lines" }, { OP_NODATA, 'u', NULL, "utf", "use UTF mode" }, { OP_NODATA, 'V', NULL, "version", "print version information and exit" }, { OP_NODATA, 'v', NULL, "invert-match", "select non-matching lines" }, @@ -2115,7 +2119,7 @@ while (ptr < endptr) /* Just count if just counting is wanted. */ - else if (count_only) count++; + else if (count_only || show_total_count) count++; /* When handling a binary file and binary-files==binary, the "binary" variable will be set true (it's false in all other cases). In this @@ -2458,7 +2462,7 @@ while (ptr < endptr) /* End of file; print final "after" lines if wanted; do_after_lines sets hyphenpending if it prints something. */ -if (!show_only_matching && !count_only) +if (!show_only_matching && !(count_only|show_total_count)) { do_after_lines(lastmatchnumber, lastmatchrestart, endptr, printname); hyphenpending |= endhyphenpending; @@ -2482,9 +2486,11 @@ if (count_only && !quiet) if (printname != NULL && filenames != FN_NONE) fprintf(stdout, "%s:", printname); fprintf(stdout, "%d" STDOUT_NL, count); + counts_printed++; } } +total_count += count; /* Can be set without count_only */ return rc; } @@ -2793,6 +2799,7 @@ switch(letter) case 'q': quiet = TRUE; break; case 'r': dee_action = dee_RECURSE; break; case 's': silent = TRUE; break; + case 't': show_total_count = TRUE; break; case 'u': options |= PCRE2_UTF; utf = TRUE; break; case 'v': invert = TRUE; break; case 'w': process_options |= PO_WORD_MATCH; break; @@ -3688,6 +3695,16 @@ for (; i < argc; i++) if (frc > 1) rc = frc; else if (frc == 0 && rc == 1) rc = 0; } + +/* Show the total number of matches if requested, but not if only one file's +count was printed. */ + +if (show_total_count && counts_printed != 1 && filenames != FN_NOMATCH_ONLY) + { + if (counts_printed != 0 && filenames >= FN_DEFAULT) + fprintf(stdout, "TOTAL:"); + fprintf(stdout, "%d" STDOUT_NL, total_count); + } EXIT: #ifdef SUPPORT_PCRE2GREP_JIT diff --git a/testdata/grepoutput b/testdata/grepoutput index 8e1f68c..4dc521b 100644 --- a/testdata/grepoutput +++ b/testdata/grepoutput @@ -787,3 +787,35 @@ RC=0 37204,12 37216,12 RC=0 +---------------------------- Test 113 ----------------------------- +476 +RC=0 +---------------------------- Test 114 ----------------------------- +testdata/grepinput:469 +testdata/grepinput3:0 +testdata/grepinput8:0 +testdata/grepinputv:1 +testdata/grepinputx:6 +TOTAL:476 +RC=0 +---------------------------- Test 115 ----------------------------- +testdata/grepinput:469 +testdata/grepinputv:1 +testdata/grepinputx:6 +TOTAL:476 +RC=0 +---------------------------- Test 116 ----------------------------- +476 +RC=0 +---------------------------- Test 117 ----------------------------- +469 +0 +0 +1 +6 +476 +RC=0 +---------------------------- Test 118 ----------------------------- +testdata/grepinput3 +testdata/grepinput8 +RC=0