151

有人可以帮我在 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 "-")
4

8 回答 8

372

要将十六进制转换为十进制,有很多方法可以在 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 -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
于 2012-11-07T23:36:18.013 回答
48

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

echo $((0x2f))
47

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

感谢Peter Leung提供的解决方案。

于 2014-04-04T12:48:47.103 回答
14

使用 shell 的另一种方法(bash 或 ksh,不适用于 dash):

echo $((16#FF))
255
于 2013-05-14T07:26:49.117 回答
13

您可以在 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桌面计算”。它还将从标准输入中获取输入,例如bc,但不是使用“操作顺序”,而是使用堆叠(“反向波兰语”)表示法。你给它添加到堆栈中的输入,然后给它从堆栈中弹出项目的操作符,然后推回结果。

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

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

您可以使用 dc 构建极其复杂的数学解决方案。在您的工具箱中拥有 shell 脚本是一件好事。

于 2012-11-08T00:21:01.643 回答
7

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

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

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

于 2015-11-12T21:36:35.113 回答
4

当变量为空(或空)时,会出现报告的错误:

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

这可能是因为给 bc 的值不正确。那很可能是 bc 需要大写值。它需要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 的唯一区别。

于 2015-08-29T22:34:54.247 回答
4

最短的方式:

$ echo $[0x3F]
63
于 2020-10-27T17:37:08.960 回答
2

我的 $PATH 上有这个方便的脚本来过滤0x1337-like; 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
于 2020-11-16T16:27:05.623 回答