Skip to main content

Counting non-null bytes of a file

·399 words·2 mins

I first needed this while running GNU ddrescue on a friend’s dying hard drive. Bad reads often show up as null (0x00) padding in the image. Counting non-null bytes was a rough “how much did we salvage?” signal — and, stacked against their memory of how full the disk had been, a ballpark % recovered.

Same idea shows up elsewhere: sparse dumps, padded blobs, firmware images, or any file where “how much real payload is in here?” matters more than stat size.

Simple count
#

Strip nulls with sed, then count bytes with wc -c:

sed 's/\x00//g' /path/to/file | wc -c

That is the whole trick: delete \x00, measure what remains. On a rescue image, treat the result as salvaged payload bytes (not a forensic guarantee — legitimate data can contain nulls too — but good enough for a recovery estimate).

Large files need progress
#

Rescue images are huge. The pipeline can run a long time with no feedback. Put pv in front so you see throughput and ETA:

pv /path/to/file | sed 's/\x00//g' | wc -c

pv reads the file, shows how much has been consumed, and feeds sed the same stream.

Two meters: input vs non-null output
#

If you want bytes read and non-null (salvaged) bytes so far side by side, use two named pv stages (-N) and keep the counters on screen (-c):

pv -N in -c /path/to/file | sed 's/\x00//g' | pv -N out -c | wc -c
MeterMeaning
inProgress through the image / original file
outNon-null bytes emitted after sed
wc -cFinal non-null total when the pipe finishes

Rough recovery % (if you trust a “disk was about F% full” memory):

recovered ≈ (non_null_bytes / image_size) / (F / 100)

Or simpler: compare non_null_bytes to F% × original_disk_size when you know the drive capacity.

Notes
#

  • Needs a sed that understands \x00 in the replacement pattern (GNU sed is the usual case on Linux).
  • This streams; it does not load the whole file into a single string. Still, sed byte-rewriting is not the fastest tool for multi‑GB rescue images — fine for ops one-offs, not a benchmark harness.
  • For a quicker strip on many systems, tr -d '\000' can replace sed in the same pipeline shape if you only care about deleting nulls.
  • Nulls ≠ only failed reads; use this as an estimate, not proof of file-level recovery.
Reyn Hartono
Author
Reyn Hartono
I build and operate systems that stay reliable and secure under real load. Open to senior roles in backend and SRE/infra, and to technical leadership — remote, globally.