Intereting Posts
Не удается загрузить FreeBSD после установки popd pushd, dirstack хранит доступные каталоги в виде текстового списка где-нибудь? Итеративно отредактируйте один файл Не удается открыть google chrome stable на элементарной os freya Блокировать подключение к Интернету через терминал на OSX Интерфейс для Linux для диапазона IP для деления входящего трафика список всех компонентов компьютера ARM в Linux? Как установить лабораторию обработки изображений Aforge на Linux с помощью Wine Извлечь информацию о шаге из аудиофайла Почему нет «евроанглийского» языка? Может ли система Linux иметь два IP одновременно? iptables: нет цепочки / цели / соответствия этим именем Установить компьютер на приостановку после определенного времени, когда он не вошел в систему? Найти все файлы и использовать результат в шаблоне поиска grep Как получить загрузку процессора по ядру в процентах?

как прочитать нуль-завершенную строку из двоичного файла

У меня есть двоичный файл, который заполнен значениями FF . Я заполнил свой старт многими \000 . Затем я добавил его начало с 10 \000 , чтобы получить какое-то смещение, а затем написал более короткую строку, также заканчивающуюся \000

Я использовал этот printf :

printf \000\000\000\000\000\000\000\000\000\000MAC_ADDRESS=12:34:56:78:90,PCB_MAIN_ID=m/SF-1V/MAIN/0.0,PCB_PIGGY1_ID=n/SF-1V/PS/0.0,CSL_HW_VARIANT=D\000' > eeprom

Вот как это выглядит, когда я показываю hexdump файла

введите описание изображения здесь

Теперь я хочу узнать, как я могу прочитать строку. Я могу использовать MY_STR=${eeprom:OFFSET} ( eeprom – это имя файла), который даст мне строку, но также даст мне остальную часть файла, который мне не нужен. Как я могу остановить это, когда это впервые сталкивается с \000 ?

  • Не могу использовать MY_STR=${eeprom:OFFSET:LENGTH} потому что длина строки неизвестна
  • Другое дело – как я могу снова заполнить его FF ?
  • Использование sh (busybox)

РЕДАКТИРОВАТЬ

Попытка сделать небольшой пример этого … У меня есть один файл input с этими значениями (после xxd -c 1 input ):

 0000000: 68 h 0000001: 65 e 0000002: 6c l 0000003: 6c l 0000004: 6f o 0000005: 2c , 0000006: 20 0000007: 00 . 0000008: 69 i 0000009: 74 t 000000a: 27 ' 000000b: 73 s 000000c: 20 000000d: 6d m 000000e: 65 e 000000f: 2c , 0000010: 00 . 

и у меня есть этот скрипт s.sh :

 BUF="" for c in $(xxd -p input); do if [ "${c}" != 00 ]; then BUF="$BUFc"; else break; fi done echo $BUF 

и я ожидал, что эхо “привет”, однако, ничего не печатается

Решение 1: прямое присвоение переменной

Если все, что вас беспокоит, это нулевые байты, то вы должны просто иметь возможность напрямую считывать данные из файла в переменную, используя любой стандартный метод, который вы предпочитаете, т.е. вы должны иметь возможность просто игнорировать нулевые байты и читать данные из файла. Вот пример использования команды cat и подстановки команд:

 $ data="$(cat eeprom)" $ echo "${data}" MAC_ADDRESS=12:34:56:78:90,PCB_MAIN_ID=m/SF-1V/MAIN/0.0,PCB_PIGGY1_ID=n/SF-1V/PS/0.0,CSL_HW_VARIANT=D 

Это сработало для меня внутри контейнера BusyBox Docker.

Решение 2. Использование xxd и цикла for

Если вам нужно больше контроля, чем вы можете использовать xxd для преобразования байтов в шестнадцатеричные строки и перебора этих строк. Затем, перебирая эти строки, вы можете применить любую логику, какую захотите, например, вы можете явно пропустить начальные нулевые значения и распечатать остальные данные, пока не достигнете некоторого условия прерывания.

Вот скрипт, который задает «белый список» допустимых символов (ASCII с 32 по 127), обрабатывает любую подпоследовательность других символов как разделитель и извлекает все допустимые подстроки:

 #!/bin/sh # get_hex_substrings.sh # Get the path to the data-file as a command-line argument datafile="$1" # Keep track of state using environment variables inside_padding_block="true" inside_bad_block="false" # NOTE: The '-p' flag is for "plain" output (no additional formatting) # and the '-c 1' option specifies that the representation of each byte # will be printed on a separate line for h in $(xxd -p -c 1 "${datafile}"); do # Convert the hex character to standard decimal d="$((0x${h}))" # Case where we're still inside the initial padding block if [ "${inside_padding_block}" == "true" ]; then if [ "${d}" -ge 32 ] && [ "${d}" -le 127 ]; then inside_padding_block="false"; printf '\x'"${h}"; fi # Case where we're passed the initial padding, but inside another # block of non-printable characters elif [ "${inside_bad_block}" == "true" ]; then if [ "${d}" -ge 32 ] && [ "${d}" -le 127 ]; then inside_bad_block="false"; printf '\x'"${h}"; fi # Case where we're inside of a substring that we want to extract else if [ "${d}" -ge 32 ] && [ "${d}" -le 127 ]; then printf '\x'"${h}"; else inside_bad_block="true"; echo fi fi done if [ "${inside_bad_block}" == "false" ]; then echo fi 

Теперь мы можем проверить это, создав файл примера, в котором есть подпоследовательности \x00 и \xff разделяющие подстроки:

 printf '\x00\x00\x00string1\xff\xff\xffstring2\x00\x00\x00string3\x00\x00\x00' > data.hex 

И вот результат, который мы получаем при запуске скрипта:

 $ sh get_hex_substrings.sh data.hex string1 string2 string3 

Решение 3. Использование команд tr и cut

Вы также можете попробовать использовать команды tr и cut для обработки нулевых байтов. Вот пример извлечения первой строки с нулевым символом в конце из списка строк с нулевым символом в конце путем сжатия / свертывания смежных нулевых символов и преобразования их в символы новой строки:

 $ printf '\000\000\000string1\000\000\000string2\000\000\000string3\000\000\000' > file.dat $ tr -s '\000' '\n' < file.dat | cut -d$'\n' -f2 string1