Skip to content
shellhacks.dev
Text Processing

Find Files Containing All of Several Words with grep

Find files that contain every one of several words by chaining grep -l into xargs. Use -Z and -0 so file names with spaces survive the pipe.

1 min read
Summarize in AI

You want files that contain red, green and blue anywhere, in any order, and a single grep pattern cannot express that.

Shell
echo 'red green blue' > a.txt
echo 'red blue' > b.txt
echo 'green blue red' > 'c d.txt'
grep -l red *.txt | xargs grep -l green | xargs grep -l blue
echo "--- null separated"
grep -lZ red *.txt | xargs -0 grep -lZ green | xargs -0 grep -l blue
Text
grep: c: No such file or directory
grep: d.txt: No such file or directory
a.txt
--- null separated
a.txt
c d.txt

grep -l red *.txt lists the files with the first word, and xargs grep -l green searches only those, so each stage narrows the list. The first pipeline in the run loses c d.txt: xargs splits on whitespace, and grep reports c and d.txt as two missing files. Adding -Z to grep and -0 to xargs passes the names separated by NUL bytes, and the file was found. Both options are in the grep manual.

Each stage reads its files again, which is fine for dozens of files and slow across a huge tree. The last stage needs no -Z unless more stages follow. All words must be literal strings or patterns that grep understands on a single line.

Taggedgreptext
Share

More snippets

Text Processing

Replace Only the Nth Match on a Line with sed

Replace only the second or a later match on a line with a numeric flag on the s command, and add g to replace from that match onward. The count restarts on every line.

1 min read

Get new posts by email

One email when a new post is published. No spam.

Unsubscribe in one click. No spam, ever.