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

问题描述 投票:0回答:8

有人可以帮我在 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 "-")
bash shell hex decimal
8个回答
410
投票

要从十六进制转换为十进制,有很多方法可以在 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

$ node -e "console.log(parseInt('FF', 16))"
255

$ rhino -e "print(parseInt('FF', 16))"
255

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

52
投票

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

echo $((0x2f))
47

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

此解决方案归功于 Peter Leung


16
投票

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

echo $((16#FF))
255

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

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

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

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


10
投票

在 dash 和其他 shell 中,你可以使用

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

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


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 的唯一区别。


4
投票

最短的路:

$ echo $[0x3F]
63

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
© www.soinside.com 2019 - 2024. All rights reserved.