Другой подход, поэтому другой ответ от меня.
Вы можете использовать ddrescue для поиска нулей. Используйте --generate-mode .
Когда ddrescue вызывается с --generate-mode он работает в "режиме генерации", который отличается от "режима восстановления" по умолчанию. То есть, если вы используете --generate-mode , ddrescue ничего не спасет. Он только пытается сгенерировать mapfile для последующего использования.
[...]
В некоторых случаях ddrescue может сгенерировать приблизительный mapfile из infile и (частичной) копии в outfile , что почти так же хорошо, как точный mapfile . Это можно сделать, просто предполагая, что сектора, содержащие все нули, не были спасены.
[...]
ddrescue --generate-mode infile outfile mapfile
(источник)
Давайте предположим, что ваш файл outfile от предыдущего запуска ddrescue Мы не можем использовать его как infile (поскольку ddrescue отказывается работать, когда infile и outfile - это один и тот же файл), нам нужен фиктивный файл, подойдет /dev/zero . Чтобы найти каждый ноль, вам нужно -b 1 . Это команда (mapfile не должен существовать):
ddrescue -b 1 --generate-mode /dev/zero file mapfile
Каждая запись с ? в списке блоков данных внутри mapfile означает блок нулей (при -b 1 один ноль также является блоком). Смотрите структуру файла карты для ddrescue. Затем вы можете получить информацию из mapfile .
Например, следующая команда даст вам длину (шестнадцатеричное, в байтах из-за -b 1) наибольшего блока нулей (пустой вывод означает, что его не было):
grep '0x.*0x.*[?]' mapfile | awk -F ' ' '{print $2}' | sort -ru | head -n 1
Чтобы ускорить процесс, вы можете использовать больший размер блока (-b), но тогда блоки нулей, начинающиеся в одном блоке и заканчивающиеся в следующем, могут остаться незамеченными, даже если они немного длиннее выбранного размера блока; их смещение становится важным.
Чтобы не пропустить ни одного отрезка нулей длиной N или более, вам необходим размер блока не более M=$(((N+1)/2)) байтов (например, не более 5 для N=10 , 6 для N=11) Команда
ddrescue -b "$M" --generate-mode /dev/zero file mapfile
сгенерирует mapfile где каждая строка с ? в списке блоков данных подразумевается не менее M нулей (с правым смещением), но каждый отрезок из N нулей (независимо от его смещения) будет генерировать такую линию наверняка. Поскольку два блока из M имеют по меньшей мере N , применяются следующие соображения:
Принимая строки с ? из списка блоков данных,
- если длина (второй столбец в
mapfile , помните, что единицей является M) равна 0x2 или больше, тогда у вас есть N или более нулей в этой позиции;
- если длина равна
0x1 то вам следует продолжить исследование, если вокруг этой позиции есть хотя бы N нулей;
- если такой строки нет, то в файле наверняка нет натяжения
N нулей.
На самом деле они всегда будут кратны 512 байтам и всегда начинаются с адреса 512 байт.
В этом случае
ddrescue -b 512 --generate-mode /dev/zero file mapfile
найдет и сопоставит их всех.