I have a shell script which uses find -print0
to save a list of files to be processed into a temporary file. As part of the logging I'd like to output the number of files found, and so I need a way to get that count. If the -print0
option weren't being used for safety I could use wc -l
to get the count.

- 2,588
- 1
- 19
- 16
3 Answers
Some options:
tr -cd '\0' | wc -c
tr '\n\0' '\0\n' | wc -l # Generic approach for processing NUL-terminated
# records with line-based utilities (that support
# NUL characters in their lines like GNU ones).
grep -cz '^' # GNU grep
sed -nz '$=' # recent GNU sed, no output for empty input
awk -v RS='\0' 'END{print NR}' # not all awk implementations
Note that for an input that contains data after the last NUL character (or non-empty input with no NUL characters), the tr
approaches will always count the number of NUL characters, but the awk
/sed
/grep
approaches will count an extra record for those extra bytes.

- 544,893
-
I measured these on 5 GB of random data (
head -c 5G /dev/urandom > f
). Results: grep 1.7s (same forgrep -Fcz ''
) • tr+wc-c 7.7s • tr+wc-l 7.4s • sed 34.7s • awk 1m11.7s – Socowi Apr 23 '20 at 13:24 -
@Socowi, YMMV with the implementation and locale. With GNU
awk
, you'll want to set the locale toC
(or any that doesn't use multibyte characters),LC_ALL=C awk ... < f
– Stéphane Chazelas Apr 23 '20 at 15:45 -
Thanks for the hint. I already used
LC_ALL=C
onsort
where it didn't speed things up, therefore Luckily I have still have the file from before:LC_ALL=C awk ...
takes 6.7s. – Socowi Apr 23 '20 at 15:50
The best method I've been able to think of is using grep -zc '.*'
. This works, but it feels wrong to use grep with a pattern which will match anything.

- 2,588
- 1
- 19
- 16
With perl
:
perl -0ne 'END {print $.}'
or:
perl -nle 'print scalar split "\0"'
or:
perl -nle 'print scalar unpack "(Z*)*", $_'

- 153,898
-
The first one will count an extra record if there is data after the last NUL. The 2 other ones don't work if the input contains newline characters. – Stéphane Chazelas Nov 04 '14 at 14:33
-
-
I would just keep the first one, and mention the fact that it counts a non-delimited record (contrary to
wc -l
) as a note (as it may be wanted). – Stéphane Chazelas Nov 04 '14 at 14:50
head
andtail
on null-delimited input in bash? – Stéphane Chazelas Oct 30 '14 at 14:06