2

Вопрос:

  • Есть ли известный инструмент для преобразования файла, состоящего из 2-байтового Hex в ASCII?

Примечание: - Сохраняйте смещение файла в байтах

Пример:

Содержание файла:

00000000  0054 0065 0073 0074 0020 0054 0065 0073
00000008  0074 0020 0054 0065 0073 0074 0020 0054
00000016  0065 0073 0074 0020 0054 0065 0073 0074
00000024  0020 0054 0065 0073 0074 0020 0054 0065
00000032  0073 0074 0020 0054 0065 0073 0074 0020
00000040  0054 0065 0073 0074 000a 0054 0065 0073
00000048  0074 0020 0054 0065 0073 0074 0020 0054
00000056  0065 0073 0074 0020 0054 0065 0073 0074
00000064  0020 0054 0065 0073 0074 0020 0054 0065

Ожидаемый результат

00000016  0065 0073 0074 0020 0054 0065 0073 0074  |est Test Test Te|
00000032  0073 0074 0020 0054 0065 0073 0074 0020  |st Test Test.Tes|
00000048  0074 0020 0054 0065 0073 0074 0020 0054  |t Test Test Test|
00000064  0020 0054 0065 0073 0074 0020 0054 0065  | Test Test Test |

3 ответа3

6

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

hexdump -e '"%08_ad  "  8/1 "%04x "' -e '"" 0/0 "" "\n"' original_file

К сожалению, xxd -r не может справиться с десятичными смещениями.

Вот короткая программа Gnu AWK, которая даст вам результат, который вы ищете:

gawk '{printf "%s  |", $0; for (f=2; f<=9; f++) { c = strtonum("0x" $f); if (c >= 32 && c <= 126) printf "%c",c; else printf "."}; printf "|\n"}' input_file

Если вы используете AWK, отличный от gawk , вы можете использовать здесь функцию strtonum() .

Вот еще один способ сделать то же самое, что и скрипт gawk выше:

cut -c 11- input_file | sed 's/\<00//g' | xxd -r -p | hexdump -e '"%08_ad  "  8/1 "%04x " ""' -e '"  |" 8/1 "%_p" "|\n"'

Если вместо этого вы хотите преобразовать ваш входной файл в текст:

cut -c 11- input_file | xxd -r -p
4
iconv -f utf-16be -t ascii input.txt
1

Чтобы удалить 0x00, в Unix вы можете использовать:

tr -d '\0'

Для отображения вы можете использовать объект dump (od) и фильтровать вывод.

od -w$1 -v -t x1a $2

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

od -w$1 -v -t x1a $2 | awk '$0~/^[0-9A-Fa-f]/ {for (i=2; i<=NF; i++) {printf "%2s ", $i; if (i%2) printf " "}; printf "  "; next} {for (i=1; i<=NF; i++) {printf "%4s ", $i; if (!(i%2)) printf "  "}; printf "\n"}'

Замените $ 2 на количество байтов, которые вы хотите отобразить. Дает вам первый шаг, вам нужно фильтровать каждый второй байт (0x00)

Надеюсь, это поможет.

Пример ниже приведен для простого ascii, но сделать это для 2-байтового файла было бы почти таким же.

00000000  23 21 2f 62 69 6e 2f 73  68 0d 0a 0d 0a 23 20 6f  |#!/bin/sh....# o|
00000010  64 20 2d 77 24 31 20 2d  76 20 2d 74 20 78 31 61  |d -w$1 -v -t x1a|
00000020  20 24 32 20 7c 20 61 77  6b 20 27 24 30 7e 2f 5e  | $2 | awk '$0~/^|
00000030  5b 30 2d 39 41 2d 46 61  2d 66 5d 2f 20 7b 70 72  |[0-9A-Fa-f]/ {pr|
00000040  69 6e 74 66 20 22 25 73  22 2c 20 24 30 20 3b 20  |intf "%s", $0 ; |
00000050  6e 65 78 74 7d 20 7b 70  72 69 6e 74 7d 27 20 7c  |next} {print}' ||
00000060  20 73 65 64 20 27 73 2f  5e 5b 30 2d 39 61 2d 66  | sed 's/^[0-9a-f|
00000070  41 2d 46 5d 2a 5b 20 09  5d 2a 2f 2f 27 20 7c 20  |A-F]*[ .]*//' | |
00000080  73 65 64 20 27 73 2f 5b  20 09 5d 5b 20 09 5d 2a  |sed 's/[ .][ .]*|
00000090  2f 09 2f 67 27 0d 0a 6f  64 20 2d 77 24 31 20 2d  |/./g'..od -w$1 -|
000000a0  76 20 2d 74 20 78 31 61  20 24 32 20 7c 20 61 77  |v -t x1a $2 | aw|
000000b0  6b 20 27 24 30 7e 2f 5e  5b 30 2d 39 41 2d 46 61  |k '$0~/^[0-9A-Fa|
000000c0  2d 66 5d 2f 20 7b 66 6f  72 20 28 69 3d 32 3b 20  |-f]/ {for (i=2; |
000000d0  69 3c 3d 4e 46 3b 20 69  2b 2b 29 20 7b 70 72 69  |i<=NF; i++) {pri|
000000e0  6e 74 66 20 22 25 32 73  20 22 2c 20 24 69 3b 20  |ntf "%2s ", $i; |
000000f0  69 66 20 28 69 25 32 29  20 70 72 69 6e 74 66 20  |if (i%2) printf |
00000100  22 20 22 7d 3b 20 70 72  69 6e 74 66 20 22 20 20  |" "}; printf "  |
00000110  22 3b 20 6e 65 78 74 7d  20 7b 66 6f 72 20 28 69  |"; next} {for (i|
00000120  3d 31 3b 20 69 3c 3d 4e  46 3b 20 69 2b 2b 29 20  |=1; i<=NF; i++) |
00000130  7b 70 72 69 6e 74 66 20  22 25 34 73 20 22 2c 20  |{printf "%4s ", |
00000140  24 69 3b 20 69 66 20 28  21 28 69 25 32 29 29 20  |$i; if (!(i%2)) |
00000150  70 72 69 6e 74 66 20 22  20 20 22 7d 3b 20 70 72  |printf "  "}; pr|
00000160  69 6e 74 66 20 22 5c 6e  22 7d 27 0d 0a           |intf "\n"}'..|
0000016d

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .