Я хочу написать скрипт (bash/awk/gawk/любой другой стандартный скрипт) на машине unix, которая имеет беззнаковое целое число в качестве аргумента программы, затем преобразует его в прямой порядок байтов и записывает байты в новый файл.
Что-то вроде этого: ./writebytes 5 outputfile.txt где 5 — это значение, которое я хочу записать в файл outputfile.txt в байтах после преобразования в формат с прямым порядком байтов.
теперь, если я сделаю шестнадцатеричный выходной файл.txt вывод должен выглядеть
0000000 0005 0000
0000004
Я очень новичок в unix и сценариях. Затем я хочу иметь возможность выводить содержимое outputfile.txt в простом десятичном удобочитаемом формате.
./readbytes outputfile.txt
и выход 5
Кстати, ваш шестнадцатеричный дамп показывает представление с прямым порядком байтов.
Это можно сделать с помощью однострочного Perl, я думаю, вы ищете что-то вроде ниже
$ hexdump <(perl -e ' $x=pack("I",5) ; print $x ')
0000000 0005 0000
0000004
если вы хотите получить в качестве параметра
$ data=5
$ perl -ne ' $x=pack("I",$_) ; print $x ' <<< "$data" > outfile.txt
$ hexdump outfile.txt
0000000 0005 0000
0000004
$ wc outfile.txt
0 0 4 outfile.txt
Чтобы прочитать его обратно в файле outfile.txt, вы снова можете использовать Perl.
$ perl -ne ' $a=unpack("I",$_); print $a ' outfile.txt
5
Использование N
в качестве формата пакета — лучший выбор, чем I
. Первый явно представляет собой 32-битное целое число без знака с прямым порядком байтов. Последний является родным C int
, который может быть или не быть прямым порядком байтов и может даже не быть 32-битным (но, вероятно, на любом аппаратном OP, который, вероятно, будет использовать). Итак: perl -e 'print pack("N", 5)' > outfile.txt
Ваш код для чтения числа из файла также будет иметь проблемы, если один из байтов будет 0x0A
. Смотрите мой ответ для лучшего подхода.
Преобразование ASCII-представления целого числа в двоичное 32-битное целое число с обратным порядком байтов с Perl легко, как уже отмечалось, а сохранение этого значения в файл — это простое перенаправление оболочки:
$ num=5
$ perl -e "print pack('N', $num)" > outputfile.txt
$ xxd outputfile.txt
00000000: 0000 0005
Примечания:
$num
в этом примере выполняется оболочкой, а не самим perl.pack("N", value)
— это perl-способ преобразования value
в 32-битное целое число с обратным порядком байтов.Для полноты, версия с прямым порядком байтов:
$ perl -e 'print pack("V", 5)' | xxd
00000000: 0500 0000
Чтение обратно из файла немного сложнее, так как это двоичные данные, а не текст, ориентированный на строки. Вы должны прочитать все 4 байта файла сразу, независимо от того, что они собой представляют. К счастью, Perl также упрощает это:
$ perl -0777 -nE 'say unpack("N", $_)' outputfile.txt
5
Аргумент -0777
— это идиоматический способ одновременного чтения всего файла в сочетании с -n
, который считывает файлы или стандартный ввод, вызывая остальную часть скрипта (предоставленную -E
) для каждого фрагмента (обычно это строка, но весь файл в Это дело)
Добавьте свой собственный код к вашему вопросу. Ожидается, что вы продемонстрируете, по крайней мере, объем исследований, которые вы вложили в решение этого вопроса самостоятельно.