Вопрос или проблема
Я пишу сценарий, похожий на xxd -i
.
Для этого мне нужен шестнадцатеричный дамп файла.
Я использую следующую команду для этого:
hexdump -v -e '8/1 "0x%02x," "\n"'
это работает нормально, когда количество байтов делится на 8:
0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,
Однако, когда количество байтов не делится на 8, он все равно форматирует несуществующие байты:
0x89,0x50,0x4e,0x47,0x ,0x ,0x ,0x ,
Можно ли заполнить байты нулями (т.е. сделать так, чтобы hexdump сообщал нулевые байты после eof) или просто “отменить” форматирование после последнего реального байта?
Ответ или решение
Для решения задачи, связанной с записью гекс-дампа файла с помощью команды hexdump
, когда количество байт не кратно 8, важно понять, как hexdump
работает с форматированием и проблемами, возникающими при формировании выходных данных. Проблема заключается в неправильном отображении данных при использовании формата, когда последние неполные группы заполняются пробелами, а не чем-то более осмысленным — например, нулями — или вовсе отменяется форматирование лишних байтов.
Теория
hexdump
— это утилита командной строки, которая помогает отображать бинарные данные в удобочитаемом шестнадцатеричном формате. Она предлагает множество параметров форматирования, включая возможность управления способом вывода информации. Условные выражения, такие как -e
, позволяют вашему скрипту печатать значения байтов в определённой последовательности и формате.
Форматная строка '8/1 "0x%02x," "\n"'
, используемая в вашей команде, разбивает данные на группы по 8 байт, каждый из которых отображается как двухзначное шестнадцатеричное число. Проблема возникает, когда файл заканчивается не на границе кратной 8; результаты форматирования становятся некорректными и содержат пробелы.
Пример
Рассмотрим файл, содержащий всего 10 байт данных. Используя вашу команду hexdump -v -e '8/1 "0x%02x," "\n"'
, результат может выглядеть следующим образом:
0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,
0x01,0x02,0x ,0x ,0x ,0x ,0x ,0x ,
Здесь после 0x01,0x02
выводятся лишние пробелы — но вы ожидаете либо полного отсутствия этих символов, либо их замены на нули (0x00
).
Приложение
Для того чтобы решить данную проблему, вам необходимо изменить способ, которым hexdump
обрабатывает вывод, либо использовать другую утилиту более сложные пост-обработки, чтобы исправить результат:
-
Заполнение нулями: Один из вариантов — предварительно дополнить файл нулями до тех пор, пока его размер не станет кратным 8. Это можно сделать вручную в преобрабатывающем скрипте. Но такой подход может быть нежелателен, так как меняет исходный файл.
-
*Специфическое ПЦ-форматирование:** Можно воспользоваться параметрами для специфического форматирования, которые игнорируют лишние данные:
hexdump -v -e '/1 "0x%02x,"' input_file | sed 's/,\s*$//'
Здесь
sed
используется для удаления завершающего запятой из последней строки, гарантируя, что она не будет показана. -
Использование других утилит: Рассмотрите возможность применения других утилит, таких как
xxd
, особенно если они предоставляют более интуитивное управление форматом вывода.xxd -c 8 -p | sed 's/\(..\)\(.*\)/0x\1\2,/' | sed 's/,$//'
Каждый из предложенных методов имеет свои преимущества и ограничения, и выбор подхода зависит от конкретных обстоятельств вашего проекта. Если требуется автоматизация, то связка bash, awk, sed и других утилит может быть особенно мощной, предоставляя вам достаточную гибкость в управлении и обработке данных.
Эффективная реализация задумки требует учёта особенностей форматирования вывода, поэтому выбирайте стратегию, не нарушающую целостность исходного файла, и учитывайте возможность более удобного отображения данных, если это необходимо. Если вы планируете писать скрипты для более сложных преобразований, то знание команд awk/sed может оказаться неоценимым дополнением к вашему арсеналу.