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 '19 at 13:10
  • You're sending all grep output to xargs. – Kusalananda Dec 18 '19 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 '19 at 13:13
  • Do you need to see the output of the first grep? – Kusalananda Dec 18 '19 at 13:14
  • Kusalananda: the first grep returns the filenames (option -l) only – scrrr Dec 18 '19 at 13:14

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
| improve this answer | |

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.