This question already has an answer here:

I have the following grep

grep -r --color -L "class public interface" * | grep "authenticate"

I want it to bring back files that don't contain "class public interface" anywhere in the file, but contain "authenticate".

But what I have is not working as expected.There is a file that I know should come up as it does not contain "class public interface" but contains "authenticate"

Is there something wrong in my command?

marked as duplicate by don_crissti, Stéphane Chazelas grep Jan 25 '18 at 10:50

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.


Just as -L searches for contents of a file without a match, -l searches for the contents of a file with a match.

So you will need to specify the -l flag in the second "grepping."

Additionally, you will need to direct the output of the first grep to the second as command line arguments. This can be done using xargs, which is a tool to read items from the standard input. Piping the file names directly would make the second grep look for the string authenticate in the file names.

so you should end up with something like

grep -r --color -L "class public interface" * | xargs grep -l "authenticate"`

Note that xargs by default splits the input on any whitespace, so if you have filenames with spaces (or worse), you'll need to use grep -Z and xargs -0 to have the file names separated by NUL bytes instead. (In GNU grep, that is. Others may be different, e.g. FreeBSD grep has --null instead.)

  • 2
    can add suggestion to use grep -rLZ .. | xargs -0 .. to avoid issues due to filenames – Sundeep Jan 25 '18 at 4:34

Not the answer you're looking for? Browse other questions tagged or ask your own question.