patternbashMajor
find -exec vs -print0 | xargs -0: when to use each
Viewed 0 times
findexecxargsprint0null delimiterfilenames with spacesbatch processing
Problem
Developers use 'find | xargs' without null delimiters, breaking on filenames with spaces, newlines, or special characters. Or they use -exec when xargs would be faster.
Solution
Use -exec for simple one-off commands. Use -print0 | xargs -0 for performance or when piping to tools that don't integrate with -exec.
# -exec: safe, runs one process per file by default
find . -name '*.tmp' -exec rm {} \;
# -exec with +: batches arguments (like xargs, but native)
find . -name '*.log' -exec gzip {} +
# -print0 | xargs -0: pipeline flexibility, parallel option
find . -name '*.csv' -print0 | xargs -0 -P4 process_file
# DANGEROUS: newline-split filenames break on spaces
find . -name '*.txt' | xargs cat # BAD
# -exec: safe, runs one process per file by default
find . -name '*.tmp' -exec rm {} \;
# -exec with +: batches arguments (like xargs, but native)
find . -name '*.log' -exec gzip {} +
# -print0 | xargs -0: pipeline flexibility, parallel option
find . -name '*.csv' -print0 | xargs -0 -P4 process_file
# DANGEROUS: newline-split filenames break on spaces
find . -name '*.txt' | xargs cat # BAD
Why
-print0 outputs filenames separated by null bytes (\0). xargs -0 reads null-delimited input. Null bytes cannot appear in filenames, making this approach safe for all valid filenames.
Gotchas
- -exec {} + batches multiple files per invocation (efficient); {} \; runs once per file (slower)
- xargs without -0 splits on whitespace AND newlines — both are valid in filenames
- find -exec sh -c '...' _ {} \; is needed when you want shell features per file
- On macOS, xargs does not support -P for parallel execution in all versions — use GNU xargs
- find -delete is faster than -exec rm {} \; for simple deletion
Code Snippets
find -exec vs -print0 xargs -0
# SAFE: null-delimited pipeline
find /data -name '*.log' -mtime +30 -print0 \
| xargs -0 -I{} mv {} /archive/
# FAST: batched exec (fewer forks)
find . -name '*.pyc' -exec rm {} +
# DANGEROUS: space in filename breaks this
find . -name '*.txt' | xargs wc -l # breaks on 'my file.txt'
# Shell features per file
find . -name '*.json' -print0 \
| xargs -0 -I{} bash -c 'jq . "$1" > "$1.formatted"' _ {}Context
Processing files found with find, especially when filenames may contain spaces or special characters
Revisions (0)
No revisions yet.