grep -z and Binary Data Handling in CI
grep -z treats input and output as NUL-separated records instead of newline-separated lines.
For filenames with newlines or for piping with find -print0, -z keeps records intact. Related flags control how grep handles binary input.
What it does
grep -z (--null-data) treats the input as a sequence of records separated by the NUL byte rather than newline, so a "line" can contain embedded newlines. -Z (--null) separates output filenames with NUL (for -l). Separately, grep -a (--text) forces grep to treat binary input as text, -I skips binary files, and by default grep prints "Binary file FILE matches" instead of the line.
Common usage
# safely handle NUL-separated filenames from find
find . -name '*.log' -print0 | xargs -0 grep ERROR
# NUL-separated records (e.g. from another -z tool)
grep -z "pattern" data.bin
# force text output on a file grep thinks is binary
grep -a "version" some-binary
# print NUL-separated matching filenames for xargs -0
grep -rlZ "secret" . | xargs -0 -r ...Options
| Flag | What it does |
|---|---|
| -z / --null-data | Treat input as NUL-separated records |
| -Z / --null | Output NUL after filenames (with -l) |
| -a / --text | Process binary input as if it were text |
| -I | Skip binary files entirely |
| --binary-files=<type> | binary, text, or without-match |
In CI
When piping filenames between tools, use find -print0 | xargs -0 and grep -rlZ ... | xargs -0 so names with spaces or newlines survive. If a grep over a build directory keeps printing "Binary file ... matches", add -I to skip binaries or scope the search with --include.
Common errors in CI
"Binary file FILE matches" with no line shown means grep detected NUL bytes; add -a to see the line or -I to skip such files. -z changes what a record is, so combining it with -n gives surprising numbers; it is meant for NUL-delimited streams, not normal logs. BSD/macOS grep supports -z but its binary handling differs slightly from GNU.