Files and data
Find files with null delimiters
Process filenames containing spaces and newlines by separating records with a null byte.
10 minute lesson
A Linux filename can contain any character except the null byte and / — including newlines. That makes newline-delimited filename lists ambiguous: a filename may contain a newline, and the consumer can’t tell one file from two. GNU find and xargs support null-separated records, and a null byte can never appear inside a path, so the separator is unambiguous.
Stream filenames safely
Print sizes safely:
find ./uploads -type f -print0 | while IFS= read -r -d '' file; do
wc -c < "$file"
done
-print0 ends each result with a null byte instead of a newline. On the reading side, read -d '' sets the delimiter to the null byte, so each filename arrives whole — spaces, newlines, quotes and all.
When you don’t need a shell loop, xargs -0 is the compact partner:
find ./uploads -type f -name '*.tmp' -print0 | xargs -0 rm --
xargs -0 splits its input on null bytes and passes each name as one clean argument.
Verify with hostile names
Create authorized test filenames with spaces and unusual characters — in a directory you own, made for this test:
mkdir -p /tmp/findlab && cd /tmp/findlab
touch 'plain.txt' 'has space.txt' $'new\nline.txt'
find . -type f -print0 | while IFS= read -r -d '' f; do
printf '<%s>\n' "$f"
done
Confirm every file is handled once: three files in, three records out, and the newline-bearing name stays one record. The angle brackets in the output make any accidental split visible.
The failure this replaces
The naive version is for f in $(find . -type f). Command substitution turns the results into one string, word splitting chops it on every space and newline, and has space.txt becomes two broken values. It works in a tidy demo directory and corrupts data the first time a real filename gets creative.
Two placement habits finish the job. Place fixed command options before untrusted filenames, and use -- where the command supports it, so a file named -rf is treated as a name rather than parsed as a flag.
Lesson completed