Добавление начальных нулей в шестнадцатеричное число в скрипте bash - PullRequest
0 голосов
/ 05 января 2019

Я работаю над проектом шины CAN и пытаюсь отправить сообщение, чтобы установить время и дату. Я разработал, как сообщение должно быть отформатировано, захватило дату / время и сохранено в переменных. Я преобразовал их в шестнадцатеричные просто отлично, но мне нужно добавить начальные 0 для заполнения к необходимому пространству, требуемому сообщением.

Я пробовал методы, которые видел онлайн для скрипта bash, но у меня проблема: 2019 год - 7E3 в шестнадцатеричном формате Мне нужно, чтобы это отображалось как 07E3. При использовании awk для добавления начальных 0, E3 интерпретируется как инженерная нотация * 10 ^ 3 и, следовательно, печатается как 7000. Ниже приведен мой сценарий вместе с изображением, отображающим формат сообщения шины CAN. Любая помощь приветствуется.

#!/bin/bash

#Store Date/Time in Variables
Year=`date '+%Y'`
Month=`date '+%m'`
Day=`date '+%d'`
Hour=`date '+%H'`
Minute=`date '+%M'`
Second=`date '+%S'`

#Convert Date/Time to Hexadecimel
HexYear=`echo "ibase=10;obase=16;$Year"| bc | awk '{ printf("%04d\n", $1) }'`
HexMonth=`echo "ibase=10;obase=16;$Month"| bc | awk '{ printf("%02d\n", $1) }'`
HexDay=`echo "ibase=10;obase=16;$Day"| bc | awk '{ printf("%02d\n", $1) }'`
HexHour=`echo "ibase=10;obase=16;$Hour"| bc | awk '{ printf("%02d\n", $1) }'`
HexMinute=`echo "ibase=10;obase=16;$Minute"| bc | awk '{ printf("%02d\n", $1) }'`
HexSecond=`echo "ibase=10;obase=16;$Second"| bc | awk '{ printf("%02d\n", $1) }'`

echo "The following is Decimel > Hex"
echo "$Year > $HexYear"
echo "$Month > $HexMonth"
echo "$Day > $HexDay"
echo "$Hour > $HexHour"
echo "$Minute > $HexMinute"
echo "$Second > $HexSecond"

Формат сообщения по шине CAN

Ответы [ 3 ]

0 голосов
/ 05 января 2019

Ответ в awk, как и в другом printf форматировании, - %0X, например ::

$ echo 2019 01 04 | awk '{ printf("%02X%02X%04X\n", $2, $3, $1) }'
010407E3

x для шестнадцатеричного значения, регистр цифр AF совпадает с регистром буквы, а 0 для начальных нулей, после чего вы можете указать желаемую ширину (например, дополнить до четырех цифр ведущими нулями) в верхнем регистре: %04X).

И если вам не нужен awk для чего-либо еще (например, для обработки нескольких строк), просто используйте printf напрямую:

$ printf "%02X%02X%04X\n" `date '+%m %d %Y'`
010407E3
0 голосов
/ 05 января 2019

Вы должны понять, как невероятно неэффективно звонить date 6 раз, когда вы могли бы позвонить один раз, а затем позвонить bc + awk, чтобы сделать что-то, что awk мог бы сделать один, а затем сделать ЭТО 6 раз как Что ж. Потратьте секунду, чтобы действительно подумать о том, что делает ваш скрипт.

Посмотрите на это с date плюс любой awk:

$ awk -v dec="$(date '+%Y %m %d %H %M %S')" 'BEGIN {
    split(dec,a)
    hex = sprintf("%X %X %X %X %X %X",a[1],a[2],a[3],a[4],a[5],a[5])
    print dec, "->", hex
}'
2019 01 05 08 22 06 -> 7E3 1 5 8 16 16

или с GNU awk для функций времени:

$ awk 'BEGIN {
    dec = strftime("%Y %m %d %H %M %S") 
    split(dec,a)
    hex = sprintf("%X %X %X %X %X %X",a[1],a[2],a[3],a[4],a[5],a[5])
    print dec, "->", hex
}'
2019 01 05 08 18 54 -> 7E3 1 5 8 12 12

и вернуть результат обратно в оболочку:

$ hex=( $(awk 'BEGIN{dec=strftime("%Y %m %d %H %M %S"); split(dec,a); hex=sprintf("%X %X %X %X %X %X",a[1],a[2],a[3],a[4],a[5],a[5]); print hex}') )
$ declare -p hex
declare -a hex=([0]="7E3" [1]="1" [2]="5" [3]="8" [4]="1F" [5]="1F")
0 голосов
/ 05 января 2019

Все, что echo|bc|awk может быть сведено до

$: HexYear=$( printf "%04X\n" $Year )
$: echo "$Year > $HexYear"
2019 > 07E3

X> x, так как для него не требуется объявлять переменную в верхнем регистре.

...