Different approach, therefore another answer from me.
You can use ddrescue itself to search for zeros. Use --generate-mode.
When ddrescue is invoked with the --generate-mode option it operates in "generate mode", which is different from the default "rescue mode". That is, if you use the --generate-mode option, ddrescue does not rescue anything. It only tries to generate a mapfile for later use.
[…]
ddrescue can in some cases generate an approximate mapfile, from infile and the (partial) copy in outfile, that is almost as good as an exact mapfile. It makes this by simply assuming that sectors containing all zeros were not rescued.
[…]
ddrescue --generate-mode infile outfile mapfile
(source)
Let's pretend your file is outfile from previous ddrescue run. We cannot use it as infile (because ddrescue refuses to work when infile and outfile are the same file), we need a dummy one, /dev/zero will do. To find every zero you need -b 1. This is the command (mapfile must not exist):
ddrescue -b 1 --generate-mode /dev/zero file mapfile
Every entry with ? in the list of data blocks inside the mapfile means a block of zeros (with -b 1 one zero is also a block). See mapfile structure for ddrescue. You can then retrieve information from the mapfile.
For example the following command will give you the length (hexadecimal, in bytes because of -b 1) of the largest block of zeros (empty output means there was none):
grep '0x.*0x.*[?]' mapfile | awk -F ' ' '{print $2}' | sort -ru | head -n 1
To speed things up you may want to use larger block size (-b), but then blocks of zeros that start within one block and end within the next may go unnoticed even if they are slightly longer than the chosen block size; their offset becomes important.
To not miss any stretch of zeros of length N bytes or more, you need a block size of at most M=$(((N+1)/2)) bytes (e.g. at most 5 for N=10, 6 for N=11). The command
ddrescue -b "$M" --generate-mode /dev/zero file mapfile
will generate a mapfile where every line with ? in the list of data blocks means at least M zeros (at the right offset), but every stretch of N zeros (regardless of its offset) will generate such line for sure. Since two blocks of M are at least N, the following reasoning applies:
Taking lines with ? from the list of data blocks,
- if the length (second column in the
mapfile, remember the unit is M) is 0x2 or greater then you do have N or more zeros at this position;
- if the length is
0x1 then you should investigate further if there are at least N zeros around this position;
- if there is no such line then there is no stretch of
N zeros in the file for sure.
In reality, these would be always a multiple of 512 bytes, and always begin at a 512 byte address
In this case
ddrescue -b 512 --generate-mode /dev/zero file mapfile
will find and map them all.