Obviously this can be done with a little Python/Bash script, but a command line utility that supports this would be nice.
I was going to write this utility myself, until the part where I had to implement the parsing of the combinational logic (since it can be arbitrarily nested/chained), and I didn't find tools in the language of my choice (Rust) back then to make that easy.
I did find a rust library to do just that yesterday[0], so I myself might get on it!
$ grep remote files/* | grep "machine learning"
you're welcome?
$ grep -l remote files/* | xargs grep -l "machine learning"
> allowing combinational logic like "find" does
You can still use `find` expressions for this if you really want to use them, but the above seems better for this.
$ find files -type f -exec grep -q remote {} \; -exec grep -q "machine learning" {} \; -print
Combining and using null terminators in the pipe:
$ find files -type f -exec grep -lZ remote {} + | xargs -0 grep -l "machine learning"
Using zsh extended globs:
$ printf '%s\n' files/**(.e['grep -q remote "$REPLY"']e['grep -q "machine learning" "$REPLY"'])
There are multiple options, but the ones that are basically `grep -l | xargs grep` seem best.
Not only that, I think implementing "or" logic would be quite convoluted by itself right?
$ grep -l X files/* | xargs grep -l Y | xargs grep -L Z | xargs grep -El 'A|B'
Here's an awk solution that avoids `|` in the regex:
$ find files -type f -exec awk '/X/{x=1} /Y/{y=1} /Z/{z=1} /A/{a=1} /B/{b=1} END { if (x && y && ! z && (a || b)) print FILENAME }' {} \;
Depending on what your files look like, joining the lines in the files may also be an option:
$ find files -type f -exec awk 'BEGIN{a=FILENAME}{a=a" "$0}END{print a}' {} \; | awk '/X/ && /Y/ && ! /Z/ && (/A/ || /B/) { print $1 }'
I imagine being able to write expressions like the one on this last one is what you're looking for.
All this isn't to say that there isn't space for a new tool. Certainly a tool can be made that allows expressing these more succinctly if you really want it.