How to caseless grep listing names of files containing ALL of several strings and NONE of another several strings

Question

Frequently I want to generate a list of files having the stated condition.

Suppose I want to find all files with a copyright and a main but without using fcntl or a namespace.

Here is a clumsy approach:

fgrep -i -r -l copyright *|xargs fgrep -i -l main|xargs fgrep -i -l -v fcntl|xargs fgrep -i -l namespace

Does anyone know how to achieve the same result with a more sophisticated approach using standard utilities?

For fun, I have begun to write my own C++17 program to achieve a speedy result but I would love to find my own work unnecessary. Here is my GitHub repository with that code:

https://github.com/jlettvin/Greased-Grep


Show source
| search   | performance   | grep   2017-11-29 22:11 1 Answers

Answers to How to caseless grep listing names of files containing ALL of several strings and NONE of another several strings ( 1 )

  1. 2017-11-29 23:11

    With (GNU) grep, I would do this as follows:

    grep -Flir 'main' . \
        | xargs grep -Fli 'copyright' \
        | xargs grep -FLi -e 'fcntl' -e 'namespace'
    

    This is quite similar to what you had. To get files not containing a pattern, I use the -L option (you tried -lv – that returns the files that contain at least one line that doesn't match, i.e., typically all files).

    For the last step, excluding files that don't match, I can do with just one grep invocation and multiple patterns specified with -e.

    To make this more robust and allow for any characters in filenames, you can require that grep separates filenames with a NUL byte (-Z) and xargs expecting that (-0):

    grep -FlirZ 'main' . \
        | xargs -0 grep -FliZ 'copyright' \
        | xargs -0 grep -FLi -e 'fcntl' -e 'namespace'
    

Leave a reply to - How to caseless grep listing names of files containing ALL of several strings and NONE of another several strings

◀ Go back