2019-12-29 18:59:22 -0800, Paul Eggert: [...] > > It should be > > > > grep -n -- 'f.*\.c$' *g*.h /dev/null > > Thanks, done in the attached patch. [...]
There were a few other instances. The patch below attempts to fix those (includes your patch). I've also replaced find|xargs to the standard and more portable (and simpler/faster...) find -exec + (GNU find used not to support that but that was eventually fixed over 10 years ago). I've replaced the POSIX+XSI ps -e with POSIX ps -A (for BSD compatibility). I've moved the grep -H and grep -- FAQ entries to the front so they are explained before being used. diff --git a/doc/grep.in.1 b/doc/grep.in.1 index a382966..a91b2a6 100644 --- a/doc/grep.in.1 +++ b/doc/grep.in.1 @@ -1333,13 +1333,18 @@ 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 +The +.B \-n +option outputs line numbers, the +.B \-\- +argument treats expansions of \*(lq*g*.h\*(rq starting with \*(lq\-\*(rq +as file names not options, +and the empty file /dev/null causes file names to be output 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 +$ \fBgrep\fP \-n \-\- 'f.*\e.c$' *g*.h /dev/null argmatch.h:1:/* definitions and prototypes for argmatch.c .EE .in diff --git a/doc/grep.texi b/doc/grep.texi index 873b53c..de7d028 100644 --- a/doc/grep.texi +++ b/doc/grep.texi @@ -1585,12 +1585,13 @@ 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 +The @option{-n} option outputs line numbers, the @option{--} argument +treats any later arguments starting with @samp{-} as file names not +options, and the empty file @file{/dev/null} causes file names to be output 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} +$ @kbd{grep -n -- 'f.*\.c$' *g*.h /dev/null} argmatch.h:1:/* definitions and prototypes for argmatch.c @end example @@ -1608,11 +1609,78 @@ Here are some common questions and answers about @command{grep} usage. @enumerate +@item +How do I force @command{grep} to print the name of the file? + +Append @file{/dev/null}: + +@example +grep 'eli' /etc/passwd /dev/null +@end example + +gets you: + +@example +/etc/passwd:eli:x:2098:1000:Eli Smith:/home/eli:/bin/bash +@end example + +Alternatively, use @option{-H}, which is a GNU extension: + +@example +grep -H 'eli' /etc/passwd +@end example + +Using that trick is generally wanted when using @command{find}, shell +globbing or other forms of expansions or more generally when we don't +know in advance what file are being searched in and want that +information to be returned. Without it + +@example +grep -- pattern *.txt +@end example + +could output the matched lines without indication of which file they +were found in if there was only one non-hidden @samp{.txt} file in the +current directory. + +@item +What if a pattern or filename has a leading @samp{-}? + +@example +grep -H -- '--cut here--' * +@end example + +@noindent +searches for all lines matching @samp{--cut here--}. + +@samp{--} marks the end of options. None of the arguments after +@samp{--} are treated as options even if they start with +@samp{-}. + +Alternatively, one can use @option{-e} to specify the pattern: + +@example +grep -H -e '--cut here--' -- * +@end example + +But @samp{--} is still needed to guard against filenames that +start with @samp{-}. + +Another approach would be to use: + +@example +grep -H -e '--cut here--' ./* +@end example + +Which also guards against a file called @samp{-} (which +@command{grep} would otherwise interpret as meaning standard +input). + @item How can I list just the names of matching files? @example -grep -l 'main' *.c +grep -l -- 'main' *.c @end example @noindent @@ -1630,45 +1698,33 @@ grep -r 'hello' /home/gigi searches for @samp{hello} in all files under the @file{/home/gigi} directory. For more control over which files are searched, -use @command{find}, @command{grep}, and @command{xargs}. +use @command{find} in combination with @command{grep}. For example, the following command searches only C files: @example -find /home/gigi -name '*.c' -print0 | xargs -0r grep -H 'hello' +find /home/gigi -name '*.c' -exec grep -H 'hello' '@{@}' + @end example This differs from the command: @example -grep -H 'hello' *.c +grep -H -- 'hello' *.c @end example -which merely looks for @samp{hello} in all files in the current -directory whose names end in @samp{.c}. +which merely looks for @samp{hello} in all (non-hidden) files in +the current directory whose names end in @samp{.c}. The @samp{find ...} command line above is more similar to the command: @example -grep -rH --include='*.c' 'hello' /home/gigi +grep -r --include='*.c' 'hello' /home/gigi @end example -@item -What if a pattern has a leading @samp{-}? - -@example -grep -e '--cut here--' * -@end example - -@noindent -searches for all lines matching @samp{--cut here--}. -Without @option{-e}, -@command{grep} would attempt to parse @samp{--cut here--} as a list of -options. @item Suppose I want to search for a whole word, not a part of a word? @example -grep -w 'hello' * +grep -H -w -- 'hello' * @end example @noindent @@ -1679,7 +1735,7 @@ For more control, use @samp{\<} and For example: @example -grep 'hello\>' * +grep -H -- 'hello\>' * @end example @noindent @@ -1690,38 +1746,17 @@ searches only for words ending in @samp{hello}, so it matches the word How do I output context around the matching lines? @example -grep -C 2 'hello' * +grep -H -C 2 -- 'hello' * @end example @noindent prints two lines of context around each matching line. -@item -How do I force @command{grep} to print the name of the file? - -Append @file{/dev/null}: - -@example -grep 'eli' /etc/passwd /dev/null -@end example - -gets you: - -@example -/etc/passwd:eli:x:2098:1000:Eli Smith:/home/eli:/bin/bash -@end example - -Alternatively, use @option{-H}, which is a GNU extension: - -@example -grep -H 'eli' /etc/passwd -@end example - @item Why do people use strange regular expressions on @command{ps} output? @example -ps -ef | grep '[c]ron' +ps -Af | grep '[c]ron' @end example If the pattern had been written without the square brackets, it would @@ -1788,6 +1823,9 @@ Use the special file name @samp{-}: cat /etc/passwd | grep 'alain' - /etc/motd @end example +To match in a file called @samp{-} in the current directory, use +@samp{./-}. + @item @cindex palindromes How to express palindromes in a regular expression? diff --git a/gnulib b/gnulib --- a/gnulib +++ b/gnulib @@ -1 +1 @@ -Subproject commit 575b0ecbad2f34d5777f9562eebc2d0c815bfc5c +Subproject commit 575b0ecbad2f34d5777f9562eebc2d0c815bfc5c-dirty