Unless you use the non-standard -H
or -r
/-R
options, grep
only outputs the file name if passed more than one file name, so you can do:
find . -type f -exec grep -n 'string to search' /dev/null {} +
With the {} +
syntax, find
will pass as many files as needed to grep
, while with {} ';'
, it runs one grep
per file which is inefficient.
We still add /dev/null
(which is guaranteed to exist and be empty) which makes sure grep
gets at least two files, for the cases where there's only one regular file in the current directory or below or the list of files has been split by find
in such a way that the last run has only one file.
As a side note, with -exec grep regex {} +
, find
's exit status will be non-zero if any of the grep
invocations terminated with a non-zero exit status. It will also be non-zero if find
fails to traverse/read some directories or get file metadata. If find
returns with a zero exit status, that means find
could traverse all directories and all grep
invocation succeeded (found at least one file with at least one match), but if it returns non-zero, that doesn't necessarily mean no match was found.
With -exec grep regex {} ';'
, grep
's exit status is only used to determine whether the -exec
predicate (which could be used as a condition) succeeds, it's not reflected in find
's exit status. So find
's exit status will only be about whether it could find all the files.