在bash脚本中将前导零添加到十六进制数

时间:2019-01-04 22:32:28

标签: bash awk can-bus bc

我正在研究一个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 bus message format

3 个答案:

答案 0 :(得分:1)

所有echo|bc|awk都可以简化为

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

X> x,因为它不需要将var声明为大写。

答案 1 :(得分:0)

与其他printf格式一样,awk中的答案为%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

答案 2 :(得分:0)

您必须意识到,一次只能调用6次date,然后再调用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

并将结果返回到shell中:

$ 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")