Командная строка для изменения порядка байтов / изменения порядка байтов - PullRequest
11 голосов
/ 22 июня 2011

Я взломал некоторые скрипты, пытаясь проанализировать некоторые данные, написанные Javas DataOutputStream#writeLong(...). Поскольку java всегда, по-видимому, пишет с прямым порядком байтов, у меня проблема с передачей байтов в od. Это связано с тем, что od всегда предполагает, что порядковый номер соответствует порядковому порядку арки, в которой вы находитесь в данный момент, а я на машине с прямым порядком байтов.

Я ищу простой однострочный, чтобы изменить порядок следования байтов. Допустим, вы знаете, что последние 8 байтов файла - это длинный, записанный вышеупомянутым методом writeLong(...). Моя лучшая попытка напечатать это длинное

tail -c 8 file | tac | od -t d8

, но tac только работает над текстом (достаточно справедливо). Я нашел некоторые ссылки на dd conv=swab, но это только меняет местами байты парами и не может обратить эти восемь байтов в обратном порядке.

Кто-нибудь знает хороший однострочник для этого?

Ответы [ 6 ]

8 голосов
/ 10 октября 2013

Вы можете использовать objcopy:

$ objcopy -I binary -O binary --reverse-bytes=num inputfile.bin outputfile.bin

, где num равно 2 или 4.

8 голосов
/ 22 июня 2011

В конце концов прибегнул к Perl. Использовал однострочник, который я нашел на PERL One Liners :

tail -c 8 file | perl -0777e 'print scalar reverse <>' | od -t d8

Символ-разделитель 0777 меня немного озадачил, но эта страница в администраторе Debian, похоже, предполагает, что он является заполнителем для "без разделителя записей", вызывая полный обратный байт на байт.

Другие предложения приветствуются.

РЕДАКТИРОВАТЬ: нашел другую команду в комментарии к tac.c, который я скачал из GNU coreutils:

Скопируйте каждый ФАЙЛ или стандартный ввод, если ничего не указано или когда ФАЙЛ имя "-" встречается, к стандартному выводу с порядок записей в обратном порядке. Записи разделены экземпляры строки или перевода строки, если ничего не указано. По умолчанию строка-разделитель прикрепляется к концу записи, следует в файле.

Опция: -b, --before Разделитель присоединяется к началу записи, которой предшествует файл. -r, --regex Разделитель является регулярным выражением. -s, --separator = separator Использовать SEPARATOR в качестве разделителя записей.

Чтобы инвертировать файл за байтом, используйте (в bash, ksh или sh): tac -r -s '. \ | 'file

2 голосов
/ 08 февраля 2014

Обратите внимание, что следующая версия GNU coreutils (> = 8.23) добавит параметр --endian = {little, big} к команде od

1 голос
/ 09 июля 2014

BASH:

od -b -v -w8 | while read pfx b8 ; do [ "$b8" ] && echo -n 12345678 | tr 87654321 \\${b8// /\\} ; done

Чтобы быть немного более устойчивым в зависимости от стиля вывода od, может потребоваться сжатие пробелов (вставить "| sed 's/ */ /g'" после w8).

1 голос
/ 08 марта 2013

Я придумал этот однострочный Perl для преобразования 4-байтовых целых чисел из одного порядкового номера в другой:

$ perl -e 'open F,shift; do { read(F,$a,4); print scalar reverse($a);} while(!eof(F));' bigend.bin > littlend.bin

Это, вероятно, прекрасно работает на реальных машинах с Linux, но Cygwin в конце поразил меня, рассматривая двоичный файл как текст и вставляя 0x0D (он же CR) перед каждым байтом 0x0A (он же перевод строки). Но если вы передадите трубку на cat -, то, похоже, оставите ее в покое. Это работает для меня:

$ perl -e 'open F,shift; do { read(F,$a,4); print scalar reverse($a);} while(!eof(F));' bigend.bin | cat - > littlend.bin
0 голосов
/ 28 июля 2015

Используется дд, Люк!

dd if=sourcefile of=resultfile conv=swab
...