Дано: общий двоичный файл и размер блока
Желаемый результат: копия двоичного файла, в котором все блоки, содержащие только нулевые биты/байты, были удалены/вырезаны из файла.
Мне действительно интересно, почему я не могу найти инструмент, который делает эту простую работу. Я создал небольшой скрипт, но его производительность смехотворна. Должно же быть существующее программное обеспечение, способное сделать это, не так ли?!
Возможно, проблема с поиском этого связана с тем, что существует слишком много терминов, которые можно использовать для выражения этой потребности...
Редактировать: поток sed, о котором вы говорите, заменяет каждый байт, я просто хочу заменить 0 байтов, если их идет по крайней мере столько же, сколько и блоков подряд.
Я хочу исследовать очень большой очень разреженный файл (не разреженный, как в разреженном файле в файловой системе) и для этого анализа я хочу вырезать ненужные части.
EDIT 2: Размер файла составляет порядка 10-1000 ГБ. Для небольших размеров мой медленный собственный инструмент подходит, но для таких больших файлов ...
решение1
bbe
это " sed
подобный редактор для двоичных файлов". В Debian он находится в bbe
пакете.
Было бы лучше, если бы вы могли s/^\0*$//
определить блоки, полные нулевых байтов, и удалить их. Мои тесты показывают, что такие выражения, подобные регулярным выражениям, не работают в bbe
. Вы все равно можете использовать (почти) столько, \0
сколько вам нужно:
s/\0\0…\0\0//
где …
обозначает правильное количество \0
подстрок. Если вы выберете большой размер блока, то может быть проблематично передать соответственно длинную строку через командную строку. К счастью, bbe
поддерживает чтение скрипта из файла. Действуйте так:
# The following function uses non-POSIX 'for' loop. Rewrite if necessary.
gen_script() {
printf 's/'
for ((i=0;i<"$1";i++)); do
printf '\\0'
done
printf '//\n'
}
# This needs to be a plain decimal number:
blocksize=512
gen_script "$blocksize" > bbe-script
<binary_file_in bbe -b ":$blocksize" -f bbe-script >binary_file_out
Проблемы:
- Приведенная выше реализация
gen_script
довольно медленная и непрактичная для большихblocksize
. - В моих тестах
bbe
вел себя неправильно дляblocksize
более чем16384
(т.е. блоков по 16 КиБ). Это делает первую проблему неактуальной. В этой роли
bbe
сам по себе тоже не очень быстрый. Я не знаю, насколько велик ваш "очень большой файл". Если бы я был вами, я бы попробовалpv binary_file_in | bbe -b ":$blocksize" -f bbe-script >binary_file_out
и через несколько секунд я смогу сказать, приемлемо ли расчетное время прибытия.