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?

1

There are 1 best solutions below

0
BurntSushi5 On BEST ANSWER

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.