Your approach, even if you get the escaping right, will run into problems when the number of files output by the goodword
grep
reaches the limits on command-line length. It is better to pipe the output of the first grep
onto a second grep
, like this
grep -lr -- goodword * | xargs grep -Li -- badword
This will correctly handle files with spaces in them, but it will fail if a file name has a newline in it. At least GNU grep
and xargs
support separating the file names with NUL bytes, like this
grep -lrZ -- goodword * | xargs -0 grep -Li -- badword
EDIT: Added double dashes --
to grep
invocations to avoid the case when some file names start with -
and would be interpreted by grep
as additional options.