Разделить двоичные данные с фиксированным смещением байта по позиции байта?

Походит на отличную работу для inotify-инструментов

#!/bin/bash
while true; do
  inotifywait -e modify css/app/main.less;
  lessc main.less > main.css
  sleep 1
done

Inotifywait создает часы inotify на каталоге, css/app/main.less, и ожидает, пока тот файл не изменяется. В этом случае inotifywait завершается, и lessc main.less> main.css сценарий сверху будет выполняться.

3
30.06.2015, 12:35
3 ответа

Выходит на ответ великого мэу , где он использовал данные data26.6.2015.txt .

#1

$ cat 27.6.2015_1.sh && sh 27.6.2015_1.sh 
xxd -r -p <data26.6.2015.txt >/tmp/f1
size=$(stat -c '%s' /tmp/f1)
pat=$(echo -e '\xfa\xfa\xfa\xfa')
set -- 0 $(ggrep -b -a -o "$pat" /tmp/f1 | sed 's/:.*//') $size
i=2
while [ $# -ge 2 ]
do start=$1 end=$2
   let count=$end-$start
   dd bs=1 count=$count skip=$start </tmp/f1 >/tmp/f$i
   let i=i+1
   shift
done
72900+0 records in
72900+0 records out
72900 bytes (73 kB) copied, 0.160722 s, 454 kB/s

#2

$ cat 27.6.2015_2.sh && sh 27.6.2015_2.sh 
xxd -r -p <data26.6.2015.txt >/tmp/f1
size=$(stat -c '%s' /tmp/f1)
set -- 0 $(ggrep -b -a -o -P '\xfa\xfa\xfa\xfa' /tmp/f1 | sed 's/:.*//') $size
i=2
while [ $# -ge 2 ]
do start=$1 end=$2
   let count=$end-$start
   dd bs=1 count=$count skip=$start </tmp/f1 >/tmp/f$i
   let i=i+1
   shift
done
72900+0 records in
72900+0 records out
72900 bytes (73 kB) copied, 0.147935 s, 493 kB/s

#3

$ cat 27.6.2015_3.sh && sh 27.6.2015_3.sh 
xxd -r -p <data26.6.2015.txt >r328.raw
tr -d '\n' <data26.6.2015.txt >f1
let size2=2*$(stat -c '%s' f1)
set -- 0 $(ggrep -b -a -o -P 'fafafafa' f1 | sed 's/:.*//') $size2
i=2
while [ $# -ge 2 ]
do  let start=$1/2
    let end=$2/2
    let count=$end-$start
    dd bs=1 count=$count skip=$start <r328.raw  >f$i
    let i=i+1
    shift
done
24292+0 records in
24292+0 records out
24292 bytes (24 kB) copied, 0.088345 s, 275 kB/s
24152+0 records in
24152+0 records out
24152 bytes (24 kB) copied, 0.061246 s, 394 kB/s
24152+0 records in
24152+0 records out
24152 bytes (24 kB) copied, 0.058611 s, 412 kB/s
304+0 records in
304+0 records out
304 bytes (304 B) copied, 0.001239 s, 245 kB/s

Выходит один шестнадцатеричный файл и 4 двоичных файла:

$ less f1
$ less f2
"f2" may be a binary file.  See it anyway? 
$ less f3
"f3" may be a binary file.  See it anyway? 
$ less f4
"f4" may be a binary file.  See it anyway? 
$ less f5
"f5" may be a binary file.  See it anyway? 

Должно быть только 3 файла с fafafafa, потому что я дал только три заголовка в файле data26.6.2015.txt, где содержимое последнего заголовка - корешок. Выходит в f2-f5:

$ xxd -ps f2 |head -n3
48000000fe5a1eda480000000d00030001000000cd010000010000000000
000000000000000000000000000000000000000000000100000001000000
ffffffff57ea5e5580510b0048000000fe5a1eda480000000d0003000100
$ xxd -ps f3 |head -n3
fafafafa585e0000fe5a1eda480000000d00030007000000cd0100000200
000000000000020000000000008000000000000000000000000000000000
01000000ffffffff72ea5e55b2eb0900105e000016000000010000000000
$ xxd -ps f4 |head -n3
fafafafa585e0000fe5a1eda480000000d00030007000000cd0100000300
000000000000020000000000008000000000000000000000000000000000
01000000ffffffff72ea5e55f2ef0900105e000016000000010000000000
$ xxd -ps f5 |head -n3
fafafafa585e0000fe5a1eda480000000d00030007000000cd0100000400
000000000000020000000000008000000000000000000000000000000000
01000000ffffffff72ea5e55a9f10900105e000016000000010000000000

где

  • f1 - это весь файл данных data26.6.2015.txt (не обязательно включать)
  • f2 - это заголовок файла, т.е. само начало файла data26.6.2015.txt до тех пор, пока первый заголовок fafafa (не обязательно включать)
  • f3 - это первый заголовок, верно!
  • f4 - второй заголовок, правильно!
  • f5 - третий заголовок, правильно!
2
27.01.2020, 21:16

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

fold -w2 <hexfile |
sed -e:t -e's/[[:xdigit:]]\{2\}$/\\x&/
    /f[af]$/N;/\(.\)..\1$/!s/.*\n/&\\x/;t
    /^.*\(.\)\(\n.*\)\n\(.*\n\).*/!bt
    s//\3\3\3 H_E_A_D \1 E_N_D \2\2\2/
    s/.* f//;s/a E.*//'

Это даст один шестнадцатеричный байт-код на строку - каждый с префиксом w / \ x - для каждого байта в шестнадцатеричном файле , кроме , где байтовые коды fa или ff встречаются 4 раза подряд. В этом случае вместо этого он получит маркер H_E_A_D или E_N_D , где строка H_E_A_D заменит последний из четырех \ xfa ] строки и строка E_N_D заменят первую из четырех последовательных строк \ xff , которые также должны синхронизировать байтовые смещения по номеру строки.

Примерно так:

PIPELINE | grep -C8n _

ВЫВОД:

(немного обрезано)


72596-\x8b
72597-\xfa
72598-\xfa
72599-\xfa
72600: H_E_A_D
72601-\x58
--
72660-\x00
72661: E_N_D
72662-\xff
72663-\xff
72664-\xff
72665-\x72

Итак, вы можете передать вывод вышеуказанной команды, например, в:

fold ... | sed ... | grep -n _

... чтобы получить список смещений, в которых заголовки может каждый начало, конец. С GNU grep вы можете использовать переключатель -A fter, чтобы указать, сколько байтов вы хотите видеть в контекстной последовательности - и поэтому вы можете использовать - Например, A777 . Вы можете взять такой вывод и передать его:

... | grep -A777 E_N_D | sed -ne's/\\/&&/p' | xargs printf %b

... для воспроизведения каждого двоичного байта для каждой последовательности, и можете указать номер совпадения w / -m [num] .

1
27.01.2020, 21:16

Вы можете работать с бинарным файлом без необходимости проходить через xxd. Я прогнал ваши данные обратно через xxd и использовал grep -b, чтобы показать мне байт . смещения вашего шаблона (преобразованные из гекса в графики \xfa) в двоичном коде Файл.

Я удалил с помощью sed совпадающие символы из выходного файла, чтобы оставить только числа. Затем я устанавливаю позиционный аргумент оболочки на результирующие смещения (set -- ...)

xxd -r -p <data26.6.2015.txt >/tmp/f1
set -- $(grep -b -a -o -P '\xfa\xfa\xfa\xfa' /tmp/f1 | sed 's/:.*//')

Теперь у вас есть список смещений в $1, $2, ... Затем вы можете извлечь интересующую вас часть с помощью dd, установив блок. размер до 1 (bs=1), так что он читает байт за байтом. skip= говорит, сколько байтов пропустить на входе, и считать= количество копируемых байтов.

start=$1 end=$2
let count=$end-$start
dd bs=1 count=$count skip=$start </tmp/f1 >/tmp/f2

Вышеуказанные отрывки от начала 1-го шаблона до непосредственно перед 2-м. Узор. Чтобы не включать деталь, можно добавить 4 для начала (и посчитать уменьшается на 4).

Если вы хотите извлечь все части, используйте цикл вокруг того же самого кода и добавьте начальное смещение 0 и конечное смещение размера файла в список чисел:

xxd -r -p <data26.6.2015.txt >/tmp/f1
size=$(stat -c '%s' /tmp/f1)
set -- 0 $(grep -b -a -o -P '\xfa\xfa\xfa\xfa' /tmp/f1 | sed 's/:.*//') $size
i=2
while [ $# -ge 2 ]
do start=$1 end=$2
   let count=$end-$start
   dd bs=1 count=$count skip=$start </tmp/f1 >/tmp/f$i
   let i=i+1
   shift
done

Если grep не удается работать с двоичными данными, можно использовать xxd hex dump данных. Сначала удалите все новые строки, чтобы иметь одну огромную строку, затем сделайте grep, используя неоформленные шестнадцатеричные значения, но затем разделите все смещения на 2, и сделайте dd с исходным файлом:

xxd -r -p <data26.6.2015.txt >r328.raw
tr -d '\n' <data26.6.2015.txt >f1
let size2=2*$(stat -c '%s' f1)
set -- 0 $(grep -b -a -o -P 'fafafafa' f1 | sed 's/:.*//') $size2
i=2
while [ $# -ge 2 ]
do  let start=$1/2
    let end=$2/2
    let count=$end-$start
    dd bs=1 count=$count skip=$start <r328.raw  >f$i
    let i=i+1
    shift
done
2
27.01.2020, 21:16

Теги

Похожие вопросы