command-linefile-searchripgrep

When using the ripgrep command in the Terminal how can I search for files which contain one pattern AND another pattern?


With rg I want to list all files which contain PATTERN_A and PATTERN_B, possibly on different lines, but both patterns should be in the file.

I tried

rg -l -e PATTERN_A -e PATTERN_B /path/to/dir

but this finds all files containing PATTERN_A or PATTERN_B (or both, but not only files containing both patterns).

How can I find with rg all files contain both patterns?


Solution

  • ripgrep can't really do this on its own. You could concoct something with the -U/--multiline flag, but the most robust way is to use shell pipelines and xargs.

    First, the setup:

    $ mkdir /tmp/rg-and
    $ cd /tmp/rg-and/
    $ printf "foo\nbar\nbaz\n" > a
    $ printf "foo\nbar\nquux\n" > b
    $ printf "baz\nbar\nquux\n" > c
    $ printf "foo\nbar\nquux\nbaz\n" > d
    

    And now the command:

    $ rg -l -0 foo | xargs -0 rg baz -l
    d
    a
    

    The -l/--files-with-matches flag tells ripgrep to only print the file path of files containing at least one match. The -0 flag tells ripgrep to print the file paths terminated by NUL instead of by the newline character. Piping this into xargs -0 causes each NUL terminated string from ripgrep to get turn into a CLI argument to its sub-command, rg in this case. The second rg command searches for the second term, baz and also asks ripgrep to print only the files matched. The result is a list of file paths containing both foo and baz, not necessarily on the same line.