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

时间:2012-11-07 23:31:43

标签: bash shell hex decimal

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

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

我的代码是:

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

8 个答案:

答案 0 :(得分:266)

要从十六进制转换为十进制,有很多方法可以在shell中或使用外部程序执行此操作:

使用

$ 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<<EOF
p "FF".to_i(16).to_s(10)
EOF
"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 :(得分:35)

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

echo $((0x2f))
47

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

此解决方案可归功于Peter Leung

答案 2 :(得分:13)

使用shell执行此操作的另一种方法(bash或ksh,不能使用破折号):

echo $((16#FF))
255

答案 3 :(得分: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命令是“desk calc”。它也将从stdin获取输入,如bc,但不使用“操作顺序”,而是使用堆叠(“反向波兰”)表示法。你给它添加到堆栈的输入,然后给它操作符弹出项目,然后推回结果。

在上面的命令中,我们得到了以下内容:

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

您可以使用dc构建非常复杂的数学解决方案。在shell脚本的工具箱中使用它是件好事。

答案 4 :(得分: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没有这种限制的唯一区别。

答案 5 :(得分:2)

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

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

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

答案 6 :(得分:1)

最短的方式:

$ echo $[0x3F]
63

答案 7 :(得分:0)

我在$ PATH上有这个方便的脚本来过滤类似0x1337的脚本; 1337;或"0x1337"行输入到十进制字符串(为清楚起见已扩展):

#!/usr/bin/env bash

while read data; do
  withoutQuotes=`echo ${data} | sed s/\"//g`
  without0x=`echo ${withoutQuotes} | sed s/0x//g`
  clean=${without0x}
  echo $((16#${clean}))
done