Skip to content
Latchkey

grep With find and xargs for Large Trees

find selects files and xargs feeds them to grep, scaling a search beyond what a single recursive grep filters cleanly.

When file selection is more complex than --include can express (by mtime, size, or deep glob), find plus xargs plus grep is the portable combination. The NUL-delimited form keeps it safe.

What it does

find locates files by name, type, time, or size; -print0 outputs them NUL-separated; xargs -0 passes them to grep without word-splitting on spaces or newlines. grep then searches the batch. This composes filters that a single grep cannot, and handles arbitrarily many files by batching.

Common usage

Terminal
# grep only files modified in the last day
find . -name '*.log' -mtime -1 -print0 | xargs -0 grep -n ERROR

# avoid "no such file" when find returns nothing
find . -name '*.go' -print0 | xargs -0 -r grep -l "panic"

# add filename even with a single match
find . -name '*.conf' -print0 | xargs -0 grep -H "listen"

Options

PieceWhat it does
find ... -print0Emit NUL-separated filenames
xargs -0Read NUL-separated input safely
xargs -rDo not run grep at all if input is empty (GNU)
grep -HForce the filename prefix per match
grep -hSuppress the filename when undesired

In CI

Always use -print0 with xargs -0 so filenames with spaces survive, and add xargs -r (GNU) so an empty find result does not run grep against stdin and hang or error. For a single batch, grep with one file omits the filename, so add -H when you parse file:line output downstream.

Common errors in CI

Without -r, an empty find result makes xargs run grep PATTERN with no files, so grep reads stdin and the job hangs or fails; add xargs -r or find ... | grep differently. xargs splits on whitespace without -0, so paths with spaces break into wrong arguments. The overall exit status comes from grep on the last batch, so a no-match still yields exit 1; guard with || true when appropriate.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →