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?
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.