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

zhte4eai  于 2023-05-07  发布在  Shell
关注(0)|答案(8)|浏览(228)

有人可以帮助我转换一个十六进制数到十进制数在一个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 "-")
oymdgrw7

oymdgrw71#

要从十六进制转换为十进制,有很多方法可以在shell中或使用外部程序来完成:
bash

$ echo $((16#FF))
255

bc

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

perl

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

printf

$ printf "%d\n" 0xFF
255

python

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

ruby

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

node.js

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

rhino

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

groovy

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

olhwl3o22#

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

echo $((0x2f))
47

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

这个解决方案归功于Peter Leung

iyfjxgzm

iyfjxgzm3#

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

echo $((16#FF))
255
u4vypkhs

u4vypkhs4#

在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”。它也将从标准输入中获取输入,就像bc一样,但它使用堆栈(“逆波兰”)表示法而不是使用“操作顺序”。你给予它一些输入,它把这些输入加到一个栈中,然后给它一些操作符,这些操作符把项从栈中弹出,并把结果推回。
在上面的命令中,我们得到了以下内容:

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

你可以用dc构造极其复杂的数学解。在shell脚本的工具箱中拥有它是一件好事。

y0u0uwnf

y0u0uwnf5#

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

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

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

pgccezyw

pgccezyw6#

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

$ 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没有这样的限制。

kt06eoxx

kt06eoxx7#

最短的路:

$ echo $[0x3F]
63
0h4hbjxa

0h4hbjxa8#

我在我的$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

相关问题