Subject: Re: bug#38792: man grep

From: Paul Eggert <[email-masked]>
Date: Sun, 29 Dec 2019 10:46:10 -0800

On 12/29/19 6:24 AM, Martin Simons wrote:
> It may not be the task of the grep project to provide a man page, but even then I
> feel there is an opportunity for improvement here

Right on both counts. I installed the attached patches to improve things a bit
in the next version of grep. Thanks for reporting the problem.

The GNU guidelines deprecate man pages, so extended examples should go into
doc/grep.texi where students can view them at
<https://www.gnu.org/software/grep/manual/>. So if you'd like to improve the
examples further, please suggest them as patches to doc/grep.texi in "git
format-patch" style. If they're extensive we'll also need to get the copyright
formalities done which I can fill you in about if you're interested in pursuing
this.
>From 8b7da49786e613c6ae9a2b299b1ce2187b32ed26 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Sun, 29 Dec 2019 10:35:40 -0800
Subject: [PATCH 1/2] doc: document quoting better
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Problem reported by Martin Simons (Bug#38792).
* doc/grep.texi: Fix quoting used in examples.  Say that patterns
should be quoted, use quoting more consistently in examples, and
give an example illustrating the difference between patterns and
globbing.  Don’t assume zgrep expertise in example.
* doc/grep.in.1: Likewise.  Also, reorder sections
to match GNU/Linux man-pages style.
---
 doc/grep.in.1 | 85 +++++++++++++++++++++++++++++++++++----------------
 doc/grep.texi | 50 +++++++++++++++++++++++++-----
 2 files changed, 101 insertions(+), 34 deletions(-)

diff --git a/doc/grep.in.1 b/doc/grep.in.1
index 219f37f..6258846 100644
--- a/doc/grep.in.1
+++ b/doc/grep.in.1
@@ -2,7 +2,7 @@
 .de dT
 .ds Dt \\$2
 ..
-.dT Time-stamp: "2018-05-11"
+.dT Time-stamp: "2019-12-29"
 .\" 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'
@@ -169,6 +169,11 @@ in each
 is one or patterns separated by newline characters, and
 .B grep
 prints each line that matches a pattern.
+Typically
+.I PATTERNS
+should be quoted when
+.B grep
+is used in a shell command.
 .PP
 A
 .I FILE
@@ -397,10 +402,10 @@ This is the default when there is only one file
 .BI \-\^\-label= LABEL
 Display input actually coming from standard input as input coming from file
 .IR LABEL .
-This is especially useful when implementing tools like
-.BR zgrep ,
+This can be useful for commands that transform a file's contents
+before searching,
 e.g.,
-.BR "gzip \-cd foo.gz | grep \-\^\-label=foo \-H something" .
+.BR "gzip \-cd foo.gz | grep \-\^\-label=foo \-H 'some pattern'" .
 See also the
 .B \-H
 option.
@@ -943,7 +948,18 @@ versions
 and
 .BR \e) .
 .
-.SH "ENVIRONMENT VARIABLES"
+.SH "EXIT STATUS"
+Normally the exit status is 0 if a line is selected, 1 if no lines
+were selected, and 2 if an error occurred.  However, if the
+.B \-q
+or
+.B \-\^\-quiet
+or
+.B \-\^\-silent
+is used and a line is selected, the exit status is 0 even if an error
+occurred.
+.
+.SH ENVIRONMENT
 The behavior of
 .B grep
 is affected by the following environment variables.
@@ -1271,16 +1287,9 @@ when
 .B POSIXLY_CORRECT
 is not set.
 .
-.SH "EXIT STATUS"
-Normally the exit status is 0 if a line is selected, 1 if no lines
-were selected, and 2 if an error occurred.  However, if the
-.B \-q
-or
-.B \-\^\-quiet
-or
-.B \-\^\-silent
-is used and a line is selected, the exit status is 0 even if an error
-occurred.
+.SH NOTES
+This man page is maintained only fitfully;
+the full documentation is often more up-to-date.
 .
 .SH COPYRIGHT
 Copyright 1998\(en2000, 2002, 2005\(en2018 Free Software Foundation, Inc.
@@ -1319,16 +1328,43 @@ to run out of memory.
 .PP
 Back-references are very slow, and may require exponential time.
 .
+.SH EXAMPLE
+The following example outputs the location and contents of any line
+containing \*(lqf\*(rq and ending in \*(lq.c\*(rq,
+within all files in the current directory whose names
+contain \*(lqg\*(rq and end in \*(lq.h\*(rq.
+The command also searches the empty file /dev/null,
+so that file names are displayed
+even if only one file name happens to be of the form \*(lq*g*.h\*(rq.
+.PP
+.in +2n
+.EX
+$ \fBgrep\fP \-n 'f.*\e.c$' *g*.h /dev/null
+argmatch.h:1:/* definitions and prototypes for argmatch.c
+.EE
+.in
+.PP
+The only line that matches is line 1 of argmatch.h.
+Note that the regular expression syntax used in the pattern differs
+from the globbing syntax that the shell uses to match file names.
+.
 .SH "SEE ALSO"
 .SS "Regular Manual Pages"
-awk(1), cmp(1), diff(1), find(1), gzip(1),
-perl(1), sed(1), sort(1), xargs(1), zgrep(1),
-read(2),
-pcre(3), pcresyntax(3), pcrepattern(3),
-terminfo(5),
-glob(7), regex(7).
-.SS "POSIX Programmer's Manual Page"
-grep(1p).
+.BR awk (1),
+.BR cmp (1),
+.BR diff (1),
+.BR find (1),
+.BR perl (1),
+.BR sed (1),
+.BR sort (1),
+.BR xargs (1),
+.BR read (2),
+.BR pcre (3),
+.BR pcresyntax (3),
+.BR pcrepattern (3),
+.BR terminfo (5),
+.BR glob (7),
+.BR regex(7).
 .SS "Full Documentation"
 A
 .UR https://www.gnu.org/software/grep/manual/
@@ -1345,9 +1381,6 @@ programs are properly installed at your site, the command
 .PP
 should give you access to the complete manual.
 .
-.SH NOTES
-This man page is maintained only fitfully;
-the full documentation is often more up-to-date.
 .\" Work around problems with some troff -man implementations.
 .br
 .
diff --git a/doc/grep.texi b/doc/grep.texi
index 01ad5f7..873b53c 100644
--- a/doc/grep.texi
+++ b/doc/grep.texi
@@ -14,6 +14,18 @@
 @c %**end of header
 
 @documentencoding UTF-8
+@c These two require Texinfo 5.0 or later, so use the older
+@c equivalent @set variables supported in 4.11 and later.
+@ignore
+@codequotebacktick on
+@codequoteundirected on
+@end ignore
+@set txicodequoteundirected
+@set txicodequotebacktick
+@iftex
+@c TeX sometimes fails to hyphenate, so help it here.
+@hyphenation{spec-i-fied}
+@end iftex
 
 @copying
 This manual is for @command{grep}, a pattern matching engine.
@@ -101,12 +113,12 @@ grep [@var{option}...] [@var{patterns}] [@var{file}...]
 @end example
 
 @noindent
-
 There can be zero or more @var{option} arguments, and zero or more
 @var{file} arguments.  The @var{patterns} argument contains one or
 more patterns separated by newlines, and is omitted when patterns are
 given via the @samp{-e@ @var{patterns}} or @samp{-f@ @var{file}}
-options.
+options.  Typically @var{patterns} should be quoted when
+@command{grep} is used in a shell command.
 
 @menu
 * Command-line Options::        Short and long names, grouped by category.
@@ -178,6 +190,8 @@ Use @var{patterns} as one or more patterns; newlines within
 @var{patterns} separate each pattern from the next.
 If this option is used multiple times or is combined with the
 @option{-f} (@option{--file}) option, search for all patterns given.
+Typically @var{patterns} should be quoted when @command{grep} is used
+in a shell command.
 (@option{-e} is specified by POSIX.)
 
 @item -f @var{file}
@@ -337,7 +351,7 @@ This enables a calling process to resume a search.
 For example, the following shell script makes use of it:
 
 @example
-while grep -m 1 PATTERN
+while grep -m 1 'PATTERN'
 do
   echo xxxx
 done < FILE
@@ -349,7 +363,7 @@ file:
 @example
 # This probably will not work.
 cat FILE |
-while grep -m 1 PATTERN
+while grep -m 1 'PATTERN'
 do
   echo xxxx
 done
@@ -449,12 +463,12 @@ This is the default when there is only one file
 @opindex --label
 @cindex changing name of standard input
 Display input actually coming from standard input
-as input coming from file @var{LABEL}.  This is
-especially useful when implementing tools like
-@command{zgrep}; e.g.:
+as input coming from file @var{LABEL}.
+This can be useful for commands that transform a file's contents
+before searching; e.g.:
 
 @example
-gzip -cd foo.gz | grep --label=foo -H something
+gzip -cd foo.gz | grep --label=foo -H 'some pattern'
 @end example
 
 @item -n
@@ -1565,6 +1579,26 @@ this is because @samp{.*} matches zero or more characters within a line.
 The @option{-i} option causes @command{grep}
 to ignore case, causing it to match the line @samp{Hello, world!}, which
 it would not otherwise match.
+
+Here is a more complex example session,
+showing the location and contents of any line
+containing @samp{f} and ending in @samp{.c},
+within all files in the current directory whose names
+contain @samp{g} and end in @samp{.h}.
+The command also searches the empty file @file{/dev/null},
+so that file names are displayed
+even if only one file name happens to be of the form @samp{*g*.h}.
+
+@example
+$ @kbd{grep -n 'f.*\.c$' *g*.h /dev/null}
+argmatch.h:1:/* definitions and prototypes for argmatch.c
+@end example
+
+@noindent
+The only line that contains a match is line 1 of @file{argmatch.h}.
+Note that the regular expression syntax used in the pattern differs
+from the globbing syntax that the shell uses to match file names.
+
 @xref{Invoking}, for more details about
 how to invoke @command{grep}.
 
-- 
2.17.1

>From 42eee261adf55da069fab362cccfbda00a7f88ab Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Sun, 29 Dec 2019 10:44:45 -0800
Subject: [PATCH 2/2] doc: fix typo in previous patch

---
 doc/grep.in.1 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/grep.in.1 b/doc/grep.in.1
index 6258846..f52cc87 100644
--- a/doc/grep.in.1
+++ b/doc/grep.in.1
@@ -1364,7 +1364,7 @@ from the globbing syntax that the shell uses to match file names.
 .BR pcrepattern (3),
 .BR terminfo (5),
 .BR glob (7),
-.BR regex(7).
+.BR regex (7).
 .SS "Full Documentation"
 A
 .UR https://www.gnu.org/software/grep/manual/
-- 
2.17.1