Удалите 0xff из конца двоичного флеш-изображения, используя скрипт bash - PullRequest
0 голосов
/ 08 января 2019

У меня есть инструмент, который генерирует 32-мегабайтное двоичное изображение для записи во флэш-память. Но только первые 2 МБ содержат ценные данные, остальные только 0xff. Поэтому я хотел бы удалить байты 0xff из конца файла, используя хороший скрипт bash / makefile. Я мог бы использовать голову:

head -c 2M test.bin > out.bin

Но я не знаю фактической длины, поэтому я хотел бы найти первое вхождение 0xff из конца файла в качестве ввода в заголовок или подобное.

Я запускаю свой инструмент из Makefile на cygwin, поэтому было бы хорошо, если бы он мог быть выполнен с использованием стандартных инструментов bash / makefile.

Ответы [ 3 ]

0 голосов
/ 08 января 2019
head -c -1 test.bin > out.bin

-1 удаляет последний байт.

0 голосов
/ 08 января 2019

Подсчет количества 0xFF байтов в конце вашего файла можно выполнить с помощью комбинации hexdump (или xxd, od ...) для преобразования вашего двоичного файла в поток ASCII. шестнадцатеричные значения и текстовый процессор, например, awk для подсчета. Пример:

hexdump -v -e '/1 "%02X\n"' test.bin | \
  awk '/FF/ {n += 1} !/FF/ {n = 0} END {print n}'

Затем удаление этого количества байтов из конца файла может быть выполнено, например, с помощью dd или head. Пример:

head -c -$d test.bin > results/test.bin

В общем, ваш Makefile может выглядеть так:

OUTDIR  := results
OLDBINS := $(wildcard *.bin)
NEWBINS := $(addprefix $(OUTDIR)/,$(OLDBINS))

.PHONY: all

all: $(NEWBINS)

$(OUTDIR)/%: % | $(OUTDIR)
    n=$$(hexdump -v -e '/1 "%02X\n"' $< | \
      awk '/FF/ {n += 1} !/FF/ {n = 0} END {print n}'); \
    head -c -$$n $< > $@

$(OUTDIR):
    mkdir -p $@

Существует несколько тонкостей, таких как фальшивые цели (all), автоматические переменные ($<, $@), предпосылки только для заказа (| $(OUTDIR)), расширение раскрытия в рецептах (знаки $$), создание функций (wildcard, addprefix), однострочный рецепт, использующий продолжение строки (\ в конце линий) ... но ничего сложного.

РЕДАКТИРОВАТЬ : попытаться найти более быстрое решение:

Другой вариант может быть более эффективным (примерно в 20 раз быстрее для файлов 32 МБ в моих супер-простых тестах), если доступна утилита base64 и размер ваших файлов ровно 32 МБ:

  1. base64 - код без переноса:

    base64 -w0
    
  2. Используйте sed, чтобы удалить все завершающие строки ////, за которыми следует последняя //8= в конце файла (см. base64 RFC 4648 ), чтобы понять, почему эти странные конечные тексты:

    sed -E 's#(////)*//8=$##'
    
  3. base64 -decode:

    base64 -d
    

One-вкладыш:

base64 -w0 test.bin | sed -E 's#(////)*//8=$##' | base64 -d > results/test.bin

Обратите внимание, что это может оставить один или два символа 0xFF в конце файла, в зависимости от размера входного файла и количества конечных символов 0xFF. Новый рецепт изготовления будет:

$(OUTDIR)/%: % | $(OUTDIR)
    base64 -w0 $< | sed -E 's#(////)*//8=$$##' | base64 -d > $@
0 голосов
/ 08 января 2019

Этот вкладыш sed one будет работать только в последней строке файла и удалит все завершающие байты 0xFF.

sed '$ s/\xff*$//' file > file.out
...