I am trying to accomplish the following result with bash:

  1. grep files for some substring.
  2. take the filenames (which can contain spaces) for these files and print them.
  3. after printing each filename I want to grep again, however this time inside that file only.

So the result looks like this:

it works!
it works!

I tried constructing a command like this:

grep -irl "something" . | xargs -I % sh -c 'echo "%"; cat "%" | grep -i "another thing" "%"'

Explanation: grep -l returns the filenames. Then I print those filenames with echo "%" and then I want to grep inside the file.

But no luck. What is the lesson here?

To clarify: My actual problem/goal is to find all files that contain a string A but do not contain a string B as well.

More clarification: I want something like grep A | grep -v B but I want a list of all files that matched A, as well.

  • This (didn't test) ? 2nd xargs -> grep -irl "something" . | xargs -I % sh -c 'echo "%"; cat "%" | xargs -I % grep -i "another thing" "%"
    – Jacques
    Dec 18, 2019 at 13:10
  • You're sending all grep output to xargs.
    – Kusalananda
    Dec 18, 2019 at 13:13
  • No I want to first grep to find some files and then grep inside those files. Your command seems to grep over all files twice.
    – scrrr
    Dec 18, 2019 at 13:13
  • Do you need to see the output of the first grep?
    – Kusalananda
    Dec 18, 2019 at 13:14
  • Kusalananda: the first grep returns the filenames (option -l) only
    – scrrr
    Dec 18, 2019 at 13:14

1 Answer 1


What is the lesson here?

Probably do not over-egg the pudding.

% (
>   grep -l -r -- "$patternA" . |
>   tee /dev/fd/7 |
>   xargs grep -L -- "$patternB"
> ) 7>&1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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