Создание двоичных файлов в UNIX

Этот вопрос был там некоторое время, и я подумал, что должен предложить несколько бонусных баллов, если я смогу заставить его работать.

Что я сделал…

Недавно на работе написал парсер, который конвертировал бы бинарный файл в читабельный формат. Двоичный файл не является файлом Ascii с 10101010 символами. Он был закодирован в двоичном формате. Итак, если я сделаю cat в файле, я получу следующее:

[jaypal~/Temp/GTP]$ cat T20111017153052.NEW 
==?sGTP?ղ?N????W????&Xx1?T?&Xx1?;
?d@#e?
      ?0H????????|?X?@@(?ղ??VtPOC01
cceE??k@9??W傇??R?K?i2??d@#e???&Xx1&Xx??!?
blackberrynet?/??!

??!

??#ripassword??W傅?W傆??0H??
                            #R??@Vtc@@(?ղ??n?POC01

Поэтому я использовал утилиту hexdump, чтобы файл отображал следующий контент, и перенаправил его в файл. Теперь у меня был выходной файл, который представлял собой текстовый файл, содержащий шестнадцатеричные значения.

[jaypal~/Temp/GTP]$ hexdump -C T20111017153052.NEW 
00000000  3d 3d 01 f8 73 47 54 50  02 f1 d5 b2 be 4e e4 d7  |==..sGTP.....N..|
00000010  00 01 01 00 01 80 00 cc  57 e5 82 00 00 00 00 00  |........W.......|
00000020  00 00 00 00 00 00 00 00  87 d3 f5 13 00 00 00 00  |................|
00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 01 00 10  |................|
00000040  01 01 0f 00 00 00 00 00  26 58 78 31 00 b3 54 c5  |........&Xx1..T.|
00000050  26 58 78 31 00 b4 3b 0a  00 00 ad 64 13 40 01 03  |&Xx1..;....d.@..|
00000060  23 16 65 f3 01 01 0b 91  30 19 48 99 f2 ff ff ff  |#.e.....0.H.....|
00000070  ff ff ff 02 00 7c 00 dc  01 58 00 a0 40 40 28 02  |.....|...X..@@(.|
00000080  f1 d5 b2 b8 ca 56 74 50  4f 43 30 31 00 00 00 00  |.....VtPOC01....|
00000090  00 04 0a 63 63 07 00 00  00 00 00 00 00 00 00 00  |...cc...........|
000000a0  00 00 00 65 45 00 00 b4  fb 6b 40 00 39 11 16 cd  |[email protected]...|
000000b0  cc 57 e5 82 87 d3 f5 52  85 a1 08 4b 00 a0 69 02  |.W.....R...K..i.|
000000c0  32 10 00 90 00 00 00 00  ad 64 00 00 02 13 40 01  |2........d....@.|

После множества awk, sed и cut скрипт преобразовал шестнадцатеричные значения в читаемый текст. Для этого я использовал позиционирование смещения, которое отмечало бы начальную и конечную позицию каждого преобразованного параметра. Результирующий файл после всех преобразований выглядит так

[jaypal:~/Temp/GTP] cat textfile.txt 
Beginning of DB Package Identifier: ==
Total Package Length: 508
Offset to Data Record Count field: 115
Data Source: GTP
Timestamp: 2011-10-25
Matching Site Processor ID: 1
DB Package format version: 1
DB Package Resolution Type: 0
DB Package Resolution Value: 1
DB Package Resolution Cause Value: 128
Transport Protocol: 0
SGSN IP Address: 220.206.129.47
GGSN IP Address: 202.4.210.51

Почему я это сделал

Я инженер-испытатель, и ручная проверка двоичных файлов была большой проблемой. Мне пришлось вручную анализировать смещения и использовать калькулятор, чтобы преобразовать их и проверить их по сравнению с Wireshark и графическим интерфейсом.

Теперь часть вопроса

Я хочу сделать обратное тому, что я сделал. Это был мой план -

  • Иметь легко читаемый текстовый файл ввода, который будет иметь Parameters : Values.
  • Пользователь может просто поместить значения рядом с ними (например, дата будет параметром, и пользователь может указать дату, которую он хочет, чтобы файл данных имел).
  • Сценарий вырежет всю соответствующую информацию (информацию, предоставленную пользователем) из входного текстового файла и преобразует ее в шестнадцатеричные значения.
  • После того, как файл был преобразован в шестнадцатеричные значения, я хочу закодировать его обратно в двоичный код.

Первые три шага выполнены

Проблема

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

[visdba@hw-diam-test01 ParserDump]$ cat temp_file | sed 's/.\{32\}/&\n/g' | sed 's/../& /g'
3d 3d 01 fc 73 47 54 50 02 f1 d6 55 3c 9f 49 9c
00 01 01 00 01 80 00 dc ce 81 2f 00 00 00 00 00
00 00 00 00 00 00 00 00 ca 04 d2 33 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10
01 01 0f 00 00 07 04 ea 00 00 ff ff 00 00 14 b7
00 00 ff ff 00 00 83 ec 00 00 83 62 54 14 59 00
60 38 34 f5 01 01 0b 58 62 70 11 60 f6 ff ff ff
ff ff ff 02 00 7c 00 d0 01 4c 00 b0 40 40 28 02
f1 d6 55 38 cb 2b 23 50 4f 43 30 31 00 00 00 00
00 04 0a 63 63 07 00 00 00 00 00 00 00 00 00 00

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

[jaypal~/Temp/GTP]$ cat temp.file 
==?sGTP?ղ?N????W????&Xx1?T?&Xx1?;
?d@#e?
      ?0H????????|?X?@@(?ղ??VtPOC01
cceE??k@9??W傇??R?K?i2??d@#e???&Xx1&Xx??!?
blackberrynet?/??!

??!

Итак, вопрос в следующем. Как мне закодировать его в этой форме?

Почему я хочу это сделать?

У нас не так много сообщений GTP (протокол туннелирования GPRS) в производстве. Я подумал, что если я реконструирую это, я смогу эффективно создать генератор данных и создавать свои собственные данные.

Суммируйте вещи

Там могут быть сложные инструменты, но я не хочу тратить слишком много времени на их изучение. Прошло около 2 месяцев, я начал работать над платформой *nix и просто освоил ее мощные инструменты, такие как sed и awk.

Чего я действительно хочу, так это помощи и руководства, чтобы это произошло.

Еще раз спасибо за чтение! 200 баллов ждут того, кто сможет направить меня в правильном направлении. :)

Примеры файлов

Вот образец исходного бинарного файла.

Вот пример текстового файла ввода, который позволит пользователю вводить значения

Вот пример файла, который мой сценарий создает после завершения преобразования из входного текстового файла.

Как изменить кодировку File 3 на File 1?


person jaypal singh    schedule 10.11.2011    source источник
comment
Если бы вы показали код парсера, мы могли бы пойти и начать показывать реверс. Теперь это равносильно обратному инжинирингу из одного шумного образца. Это не сработает. Возможно, если поставить на него бонус в 500 пт :)   -  person sehe    schedule 11.11.2011
comment
Если бы у меня было 500 баллов, я бы это сделал. :) Ну это не конвертация меня беспокоит. Даже после завершения преобразования результирующий файл все равно будет текстовым файлом. Единственная разница будет заключаться в том, что вместо содержимого ASCII или Decimal это будет двоичное содержимое. Моя главная задача - создать двоичный файл. Файл, когда я делаю кота, будет давать мне мусорные символы.   -  person jaypal singh    schedule 11.11.2011
comment
«Файл», созданный вашим скриптом, не является прямым шестнадцатеричным дампом «двоичного файла». Четвертый символ в «Двоичном файле» — 0xF8; четвертый символ в «Файле» кодируется как «fc». Это проблема со скачанными данными, или... что? Однако, если вы удалите cut из моей команды, оставшийся сценарий awk возьмет содержимое «Файла» и создаст двоичный вывод, содержащий точное преобразование пар шестнадцатеричных цифр в соответствующие байты в диапазоне 0x00..0xFF.   -  person Jonathan Leffler    schedule 27.11.2011
comment
Нет, это были просто образцы. Но проблема, с которой я столкнулся, заключается в том, что файл, который создает мой скрипт, является текстовым файлом, даже если содержимое внутри него может быть нетекстовым. Процесс загрузки отклоняет эти файлы, так как принимает только двоичные файлы.   -  person jaypal singh    schedule 27.11.2011
comment
Двоичный вывод из вашего скрипта, если я перенаправляю в файл, кодировка все равно сделает файл текстовым файлом, содержащим двоичные данные. Я хочу закодировать файл в двоичный файл.   -  person jaypal singh    schedule 27.11.2011
comment
Вам нужно будет определить, что вы подразумеваете под «бинарным файлом» и «процессом загрузки». Вам также может понадобиться указать платформу и другую информацию.   -  person Jonathan Leffler    schedule 27.11.2011
comment
Конечно Джон. Я указал тип файла, который мне нужно создать (двоичный файл), и тип файла, который у меня есть.   -  person jaypal singh    schedule 27.11.2011
comment
Спасибо. Я еще не уверен, что понимаю платформу. Интересно, как вы передаете файлы в «процесс загрузчика»? Это через фтп? Если да, то используете ли вы FTP в двоичном режиме или в режиме ASCII? Это может иметь значение. Учитывая 8-битную чистую файловую систему (например, в системах Unix), преобразование из исходного (двоичного) в формат шестнадцатеричного дампа, а затем (используя предоставленный мной код) для преобразования шестнадцатеричного дампа обратно в (двоичный) файл тоже чистый. Если вы работаете в системе, в которой существует различие между текстовыми и двоичными файлами, то точное двустороннее преобразование может оказаться невозможным.   -  person Jonathan Leffler    schedule 27.11.2011
comment
Спасибо Джон, я свяжусь со своей командой разработчиков и дам вам знать. В настоящее время мы используем инструмент wireshark для захвата необработанных pcap-файлов. Эти необработанные pcap-файлы передаются через инструмент под названием tcp-replay на Probe Proxy. Этот фрагмент кода добавляет дополнительную информацию в необработанный pcap и отправляет инструменту Databroker через поток tcp. Этот брокер данных создает двоичные файлы .NEW. И необработанные файлы pcap, и файлы .NEW, если я выполняю команду cat, дают мне значения мусора. Я думаю, это мое определение двоичных файлов :). Затем эти бинарные файлы поднимаются тандемными загрузчиками для загрузки в тандемную базу данных.   -  person jaypal singh    schedule 27.11.2011
comment
Спасибо, Деян, я снова отформатировал вопрос, чтобы он был немного понятнее. :)   -  person jaypal singh    schedule 29.11.2011
comment
Прочитай мой ответ. Я ответил на вопрос, а также написал для вас простой запуск сборщика пакетов на основе BASH. Возьмите этот код, закончите улучшать его.   -  person DejanLekic    schedule 29.11.2011


Ответы (5)


Вы можете использовать xxd для простого преобразования в двоичные файлы / шестнадцатеричные дампы и обратно.

данные в шестнадцатеричный

echo  Hello | xxd -p 
48656c6c6f0a

шестнадцатеричные данные

echo 48656c6c6f0a | xxd -r -p
Hello

or

echo 48 65 6c 6c 6f 0a | xxd -r -p
Hello

-p — это режим постскриптума, который позволяет вводить более свободную форму.

Это вывод из xxd -r -p text, где текст — это данные, которые вы указали выше.

==▒sGTP▒▒U<▒I▒▒▒΁/▒▒3▒▒▒▒▒▒▒▒▒bTY`84▒
                                     Xbp`▒▒▒▒▒▒▒|▒L▒@@(▒▒U8▒+#POC01
:▒ިv▒b▒▒▒▒TY`84Ud▒▒▒▒>▒▒▒▒▒▒▒!▒
blackberrynet▒/▒▒!
M
▒▒!
N
▒▒#Oripassword▒▒΁/▒▒΁/▒▒Xbp`▒@@(▒▒U8▒IvPOC01
:qU▒b▒▒▒▒▒▒TY`84U▒▒▒*:▒▒!
▒k▒▒▒#O Welcmme!
▒!
M
person Community    schedule 28.11.2011

Используя cut и awk, вы можете сделать это довольно просто, используя функцию расширения gawk (GNU Awk), strtonum():

cut -c11-60 inputfile |
awk '{ for (i = 1; i <= NF; i++)
       {
           c = strtonum("0x" $i)
           printf("%c", c);
       }
     }' > outputfile

Или, если вы используете не-GNU версию «нового awk», вы можете использовать:

cut -c11-60 inputfile |
awk '{  for (i = 1; i <= NF; i++)
        {
            s = toupper($i)
            c0 = index("0123456789ABCDEF", substr(s, 1, 1)) - 1
            c1 = index("0123456789ABCDEF", substr(s, 2, 1)) - 1
            printf("%c", c0*16 + c1);
        }
     }' > outputfile

Если вы хотите использовать другие инструменты (на ум приходят Perl и Python; другой вариант — Ruby), вы можете сделать это достаточно легко.

odx — это программа, аналогичная программе hexdump. Приведенный выше сценарий был изменен, чтобы читать «hexdump.out» в качестве входного файла, а вывод направлялся в odx вместо файла, и дает следующий вывод:

$ cat hexdump.out
00000000  3d 3d 01 fc 73 47 54 50  02 f1 d6 55 3c 9f 49 9c  |==..sGTP...U<.I.|
00000010  00 01 01 00 01 80 00 dc  ce 81 2f 00 00 00 00 00  |........../.....|
00000020  00 00 00 00 00 00 00 00  ca 04 d2 33 00 00 00 00  |...........3....|
00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 10  |................|
00000040  01 01 0f 00 00 07 04 ea  00 00 ff ff 00 00 14 b7  |................|
00000050  00 00 ff ff 00 00 83 ec  00 00 83 62 54 14 59 00  |...........bT.Y.|
00000060  60 38 34 f5 01 01 0b 58  62 70 11 60 f6 ff ff ff  |`84....Xbp.`....|
00000070  ff ff ff 02 00 7c 00 d0  01 4c 00 b0 40 40 28 02  |.....|...L..@@(.|
$ sh -x revdump.sh | odx
+ cut -c11-60 hexdump.out
+ awk '{  for (i = 1; i <= NF; i++)
        {
            #c = strtonum("0x" $i)
            #printf("%c", c);
            s = toupper($i)
            c0 = index("0123456789ABCDEF", substr(s, 1, 1)) - 1
            c1 = index("0123456789ABCDEF", substr(s, 2, 1)) - 1
            printf("%c", c0*16 + c1);
        }
     }'
0x0000: 3D 3D 01 FC 73 47 54 50 02 F1 D6 55 3C 9F 49 9C   ==..sGTP...U<.I.
0x0010: 00 01 01 00 01 80 00 DC CE 81 2F 00 00 00 00 00   ........../.....
0x0020: 00 00 00 00 00 00 00 00 CA 04 D2 33 00 00 00 00   ...........3....
0x0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10   ................
0x0040: 01 01 0F 00 00 07 04 EA 00 00 FF FF 00 00 14 B7   ................
0x0050: 00 00 FF FF 00 00 83 EC 00 00 83 62 54 14 59 00   ...........bT.Y.
0x0060: 60 38 34 F5 01 01 0B 58 62 70 11 60 F6 FF FF FF   `84....Xbp.`....
0x0070: FF FF FF 02 00 7C 00 D0 01 4C 00 B0 40 40 28 02   .....|...L..@@(.
0x0080:
$ 

Или, используя hexdump -C вместо odx:

$ sh -x revdump.sh | hexdump -C
+ cut -c11-60 hexdump.out
+ awk '{  for (i = 1; i <= NF; i++)
        {
            #c = strtonum("0x" $i)
            #printf("%c", c);
            s = toupper($i)
            c0 = index("0123456789ABCDEF", substr(s, 1, 1)) - 1
            c1 = index("0123456789ABCDEF", substr(s, 2, 1)) - 1
            printf("%c", c0*16 + c1);
        }
     }'
00000000  3d 3d 01 fc 73 47 54 50  02 f1 d6 55 3c 9f 49 9c  |==..sGTP...U<.I.|
00000010  00 01 01 00 01 80 00 dc  ce 81 2f 00 00 00 00 00  |........../.....|
00000020  00 00 00 00 00 00 00 00  ca 04 d2 33 00 00 00 00  |...........3....|
00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 10  |................|
00000040  01 01 0f 00 00 07 04 ea  00 00 ff ff 00 00 14 b7  |................|
00000050  00 00 ff ff 00 00 83 ec  00 00 83 62 54 14 59 00  |...........bT.Y.|
00000060  60 38 34 f5 01 01 0b 58  62 70 11 60 f6 ff ff ff  |`84....Xbp.`....|
00000070  ff ff ff 02 00 7c 00 d0  01 4c 00 b0 40 40 28 02  |.....|...L..@@(.|
00000080
$
person Jonathan Leffler    schedule 27.11.2011
comment
Спасибо, Джон. Ну, я уже сделал конверсионную часть скрипта. Я просто хочу закодировать этот преобразованный файл в двоичный файл. Даже после преобразования я могу просмотреть файл, просто выполнив cat. - person jaypal singh; 27.11.2011
comment
Если вы записываете выходные данные скрипта awk в файл, этот файл будет двоичным файлом с тем же содержимым, что и двоичный файл, из которого были сгенерированы выходные данные hexdump -C. Итак, учитывая вывод hexdump, вы можете восстановить исходные двоичные данные. Однако двоичные данные трудно показать, поэтому лучшее, что я могу сделать, это показать, что дамперы двоичных файлов производят выходные данные, эквивалентные тому, что hexdump -C произвело в первую очередь. - person Jonathan Leffler; 27.11.2011
comment
Я загрузил двоичный файл, мой входной файл и преобразованный файл. Мне нужен преобразованный файл, закодированный в двоичном формате. - person jaypal singh; 27.11.2011

Чтобы изменить кодировку с File3 на File1, вы используете такой скрипт:

#!/bin/bash

# file name: tobin.sh

fileName="tobin.txt"   # todo: pass it as parameter
                       #       or prepare it to be used via the pipe...
while read line; do
  for hexValue in $line; do
    echo -n -e "\x$hexValue"
  done
done < $fileName

Или, если вы просто хотите передать это и использовать как пример xxd в этом потоке:

#!/bin/bash

# file name: tobin.sh
# usage: cat file3.txt | ./tobin.sh > file1.bin

while read line; do
  for hexValue in $line; do
    echo -n -e "\x$hexValue"
  done
done

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

#!/bin/sh

# We assume the script will run on a LSB architecture.

hexDump() {
  for idx in $(seq 0 ${#buffer[@]}); do
    printf "%02X", ${buffer[$idx]}
  done
} # hexDump() function

###
# dump() dumps the current content of the buffer[] array to the STDOUT.
#
dump() {
  # or, use $ptr here...
  for idx in $(seq 0 ${#buffer[@]}); do
    printf "%c" ${buffer[$idx]}
  done
} # dump() function

# Beginning of DB Package Identifier: ==
buffer[0]=$'\x3d' # =
buffer[1]=$'\x3d' # =
size=2

# Total Package Length: 2
# We start with 2, and later on we update it once we know the exact size...
# Assuming 32bit architecture, LSB, this is how we encode number 2 (that is our current size of the packet)
buffer[2]=$'\x02'
buffer[3]=$'\x00'
buffer[4]=$'\x00'
buffer[5]=$'\x00'

# Offset to Data Record Count field: 115
# I assume this is also a 32bit field of unsigned int type
ptr=5
buffer[++ptr]=$'\x73'  # 115
buffer[++ptr]=$'\x00'
buffer[++ptr]=$'\x00'
buffer[++ptr]=$'\x00'

#hexDump
dump

Выход:

$ ./tobin2.sh | hexdump -C
00000000  3d 3d 02 00 00 00 73 00  00 00 00                 |==....s....|
0000000b

Конечно, это не решение исходного сообщения... Решение будет использовать что-то подобное для генерации двоичного вывода. Самая большая проблема заключается в том, что мы до сих пор не знаем типы полей в пакете. Мы также не знаем архитектуру (это bigendian или littleendian, 32-битная или 64-битная). Вы должны дать нам спецификацию. Например, длина упаковки какого типа? Мы не знаем этого из этого файла TXT!

Чтобы помочь вам сделать то, что вы должны сделать, вы должны найти нам спецификацию о размерах этих полей.

Обратите внимание, что это хорошее начало, хотя. Вам необходимо реализовать удобные функции, например, для автоматического заполнения буфера [] значениями из строки, закодированной шестнадцатеричными значениями. Итак, вы можете сделать что-то вроде write $offset "ff c0 d3 ba be".

person DejanLekic    schedule 28.11.2011
comment
./tobin.sh | hexdump -C создает тот же шестнадцатеричный дамп, что и выше. Ну, по крайней мере, первый кусок тот же. Я думаю, это зависит от того, какой двоичный ввод вы использовали для создания этого текстового файла с шестнадцатеричными значениями... - person DejanLekic; 29.11.2011
comment
Это выглядит действительно хорошо, Дежан. Я это попробую. У меня есть смещенные позиции в дизайн-документе. Придется поговорить с моим менеджером, можно ли опубликовать офсетное позиционирование для всех, так как это конфиденциальная и служебная информация. Но я могу поделиться некоторыми из них. Спасибо еще раз! - person jaypal singh; 29.11.2011
comment
Здесь нет необходимости раскрывать такую ​​информацию. Вы поняли из приведенного выше кода. Просто продолжайте заполнять массив buffer[] значениями и продолжайте думать об архитектуре. Я бы начал с написания функции writeUInt32(), чтобы вы могли использовать ее как writeUInt32 $offset 0xbabadeda - person DejanLekic; 29.11.2011
comment
Спасибо Деян, очень ценю вашу помощь! :) - person jaypal singh; 29.11.2011
comment
Решение, предоставленное @lain, работает без передачи значений. - person jaypal singh; 29.11.2011
comment
Я не говорю здесь о преобразовании из File3 в File1 (если вы внимательно прочитали этот код, он может вести себя точно так же, как xxd - просто замените строку fileName на fileName=$1 и вызовите его через: tobin.sh file3.txt). Самая большая проблема здесь - это формат и то, как вы генерируете правильный двоичный вывод. Потому что, например, количество параметров может варьироваться, а длина меняется, поэтому вам нужно изменить буфер и установить правильную длину, иначе приложение, которое читает этот двоичный ввод, не сможет его понять. - person DejanLekic; 29.11.2011
comment
Хм, для быстрого теста я сделал шестнадцатеричный дамп исходного файла .NEW › temp.file, а затем удалил столбец Offset и часть ASCII. Делал на нем xxd и диф двух файлов разницы не показал. Но я согласен, вы делаете отличное замечание здесь. Попробую через загрузчик загрузить файлы, созданные xxd. Если они будут отклонены, тогда начнется работа над расширением вашего скрипта. Еще раз спасибо за поднятие таких хороших моментов. Если xxd не удастся, я открою для вас отдельный вопрос с наградой в 500 баллов. :) - person jaypal singh; 29.11.2011
comment
Я делаю это не ради баунти - это просто интересная тема. Я бы сам сделал для этого приложение на D или C/C++, но, как я уже сказал, если вы действительно хотите сделать это в BASH, это возможно, но не тривиально. :) Это почти невозможно сделать, если вы не знаете спецификацию этого формата... - person DejanLekic; 29.11.2011
comment
Пожалуйста, не поймите меня неправильно. Я очень ценю, что вы потратили на это время. Надеюсь, я смогу работать над бэкэндом *nix в будущем, потому что я действительно ненавижу ОС HP Tandem Guardian и трачу слишком много времени на изучение sed и awk. Забавно, теперь я могу писать довольно крутые awk-скрипты, но я не знаю, как писать базовые шелл-скрипты. :) - person jaypal singh; 29.11.2011
comment
Я добавил исходный код tobin.sh, который можно использовать как xxd (т.е. вы можете направить ввод). Это хорошо, если у вас нет утилиты xxd. - person DejanLekic; 29.11.2011

Есть инструмент binmake, позволяющий описывать в текстовом формате некоторые бинарные данные и генерировать бинарный файл (или выводить в стандартный вывод). Он позволяет изменять порядок следования байтов и числовые форматы, а также принимает комментарии.

Сначала получите и скомпилируйте binmake (бинарная программа будет в bin/):

$ git clone https://github.com/dadadel/binmake
$ cd binmake
$ make

Создайте текстовый файл file.txt:

# an exemple of file description of binary data to generate
# set endianess to big-endian
big-endian

# default number is hexadecimal
00112233

# man can explicit a number type: %b means binary number
%b0100110111100000

# change endianess to little-endian
little-endian

# if no explicit, use default
44556677

# bytes are not concerned by endianess
88 99 aa bb

# change default to decimal
decimal

# following number is now decimal
0123

# strings are delimited by " or '
"this is some raw string"

# explicit hexa number starts with %x
%xff

Создайте свой двоичный файл file.bin:

$ ./binmake file.txt file.bin
$ hexdump file.bin -C
00000000  00 11 22 33 4d e0 77 66  55 44 88 99 aa bb 7b 74  |.."3M.wfUD....{t|
00000010  68 69 73 20 69 73 20 73  6f 6d 65 20 72 61 77 20  |his is some raw |
00000020  73 74 72 69 6e 67 ff                              |string.|
00000027

Вы также можете передать его, используя stdin и stdout:

$ echo '32 decimal 32 %x61 61' | ./binmake | hexdump -C
00000000  32 20 61 3d                                       |2 a=|
00000004
person daouzli    schedule 03.01.2017

awk не подходит для этой работы, но есть тысячи способов сделать это. Самый простой способ - это небольшая программа на C или любом другом языке, в котором явно проводится различие между символом и строкой десятичных цифр.

Однако, чтобы сделать это в awk, используйте формат printf "%c".

person thiton    schedule 10.11.2011
comment
Спасибо, Титон, преобразование не является реальной проблемой. Даже после завершения преобразования файл все равно будет файлом ascii, т.е. я могу выполнить команду cat, и она отобразит все символы. Вместо этого мне нужно создать двоичный файл, который, когда я делаю шестнадцатеричное имя файла, получаю тот же файл .NEW, что и выше. - person jaypal singh; 11.11.2011
comment
Я должен согласиться с @thiton, используя инструменты обработки текста для записи двоичных файлов, это сложно и подвержено ошибкам. Если вы хотите использовать язык сценариев, то perl и функции pack/unpack будут вашими друзьями. - person potong; 11.11.2011
comment
согласен с основной идеей, что набор инструментов unix - это не способ создания двоичных файлов, но я думаю, что видел, как люди использовали dd здесь, на S.O. делать подобные вещи? Всем удачи. - person shellter; 11.11.2011