Shell脚本中的十六进制到十进制


126

有人可以帮我在Shell脚本中将十六进制数字转换为十进制数字吗?

例如,我想bfca3000使用Shell脚本将十六进制数转换为十进制数。我基本上想要两个十六进制数的差。

我的代码是:

var3=`echo "ibase=16; $var1" | bc`
var4=`echo "ibase=16; $var2" | bc`
var5=$(($var4-$var3))               # [Line 48]

执行时,出现此错误:

Line 48: -: syntax error: operand expected (error token is "-")

另一种方法是:stackoverflow.com/questions/378829/…。本质上是相同的工具。和可能的跨站点的复制:superuser.com/questions/226163/...
西罗桑蒂利郝海东冠状病六四事件法轮功

Answers:


314

要从十六进制转换为十进制,有很多方法可以在外壳程序或外部程序中进行:

$ echo $((16#FF))
255

$ echo "ibase=16; FF" | bc
255

$ perl -le 'print hex("FF");'
255

$ printf "%d\n" 0xFF
255

$ python -c 'print(int("FF", 16))'
255

$ ruby -e 'p "FF".to_i(16)'
255

$ nodejs <<< "console.log(parseInt('FF', 16))"
255

$ rhino<<EOF
print(parseInt('FF', 16))
EOF
...
255

$ groovy -e 'println Integer.parseInt("FF",16)'
255

1
什么 ?bc是一种任意精度计算器语言:外部命令。
吉尔斯·奎诺

10
所以 ?这正是我的4条命令的目的,您可以修改问题的含义。
吉尔斯·奎诺

2
printf解决POSIX?如果是,那是最好的:)
Ciro Santilli郝海东冠状病六四事件法轮功2015年

3
在bash中,您也可以使用$((0xff)),即使用类似C的十六进制前缀代替16#,尽管N#显然更通用。
Ruslan

3
第一个bash示例易受整数溢出错误的影响,例如,echo $((077E9F2DBF49D100001#FF))溢出2 ^ 64的64位整数限制。bc处理正确。
roblogic

39

在Linux上处理非常轻量级嵌入式版本的busybox意味着许多传统命令不可用(bc,printf,dc,perl,python)

echo $((0x2f))
47

hexNum=2f
echo $((0x${hexNum}))
47

信贷彼得亮了此解决方案。


1
可以,但是要注意整数溢出错误,例如,echo $((0x077E9F2DBF49D100001))溢出64位整数整数限制2 ^ 64。bc处理得当
roblogic

13

使用Shell的另一种方法(bash或ksh,不适用于破折号):

echo $((16#FF))
255

#符号是什么意思?是否还有其他应用程序或文档可以阅读有关其使用的更多信息?
user1527227

1
这里提到:link。在6.5节的末尾说:“ ...数字采用[base#] n的形式,其中可选的底数是2到64之间的十进制数,代表算术底数,而n是该底数中的数字。省略base#,然后使用以10为底的数字。大于9的数字依次由小写字母,大写字母“ @”和“ _”表示。如果base小于或等于36,小写字母和大写字母可以互换使用,以表示10到35之间的数字。”
托马斯福克斯

11

您可以从Shell中使用各种工具。根据您最初提出的问题,Sputnick为您提供了绝佳的选择概览。他为您提供多个正确答案所花费的时间绝对值得投票。

他的清单上还没有列出一个:

[ghoti@pc ~]$ dc -e '16i BFCA3000 p'
3217698816

但是,如果您要做的只是减法,为什么还要麻烦将输入更改为以10为底呢?

[ghoti@pc ~]$ dc -e '16i BFCA3000 17FF - p 10o p'
3217692673
BFCA1801
[ghoti@pc ~]$ 

dc命令是“台计算”。它还将从stdin接受输入,例如bc,但是它使用堆叠(“ reverse Polish”)表示法代替使用“操作顺序”。您给它输入添加到堆栈中的输入,然后给它运算符从堆栈中弹出项目,然后推回结果。

在上面的命令中,我们有以下内容:

  • 16i-告诉dc接受以16为底的输入(十六进制)。不更改输出基准。
  • BFCA3000 -您的初始号码
  • 17FF -我从您的初始数字中减去的随机十六进制数字
  • - -取我们推送的两个数字,并从较早的数字中减去后一个,然后将结果推回堆栈
  • p-打印堆栈中的最后一个项目。这不会改变堆栈,所以...
  • 10o -告诉dc将其输出打印为基数“ 10”,但请记住,我们的输入编号方案当前为十六进制,因此“ 10”表示“ 16”。
  • p -再次打印堆栈中的最后一个项目...这次以十六进制显示。

您可以使用dc构建极其复杂的数学解决方案。在您的Shell脚本工具箱中拥有一个好东西。


3

当变量为空(或为空)时,将显示报告的错误:

$ unset var3 var4; var5=$(($var4-$var3))
bash: -: syntax error: operand expected (error token is "-")

发生这种情况的原因是给bc的值不正确。很有可能是bc需要UPPERcase值。它BFCA3000不需要bfca3000。这很容易用bash修复,只需使用^^扩展即可:

var3=bfca3000; var3=`echo "ibase=16; ${var1^^}" | bc`

这会将脚本更改为:

#!/bin/bash

var1="bfca3000"
var2="efca3250"

var3="$(echo "ibase=16; ${var1^^}" | bc)"
var4="$(echo "ibase=16; ${var2^^}" | bc)"

var5="$(($var4-$var3))"

echo "Diference $var5"

但是不需要使用bc [1],因为bash可以直接执行翻译和减法操作:

#!/bin/bash

var1="bfca3000"
var2="efca3250"

var5="$(( 16#$var2 - 16#$var1 ))"

echo "Diference $var5"

[1] 注意:我假设这些值可以用64位数学表示,因为差异是在原始脚本中以bash计算的。如果以64位编译,则Bash限于小于(((2 ** 63)-1))的整数。这将是与bc没有此限制的唯一区别。


3

在破折号和其他外壳中,您可以使用

printf "%d\n" (your hexadecimal number)

将十六进制数字转换为十进制。这不是bash或ksh特定的。


1
例如printf "%d" 0xff
lashgar '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.