Hexadecimal To Decimal in Shell Script

2019-01-10 00:14发布

Can someone help me in telling how to convert a hexadecimal number to decimal number in a shell script? E.g. I want to convert the hexadecimal number bfca3000 to decimal using a shell script. I basically want the difference of two hexadecimal numbers. My code is:

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

Upon executing ,I am getting the error as:

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

6条回答
Summer. ? 凉城
2楼-- · 2019-01-10 00:53

One more way to do it using the shell (bash or ksh, doesn't work with dash):

echo $((16#FF))
255
查看更多
Fickle 薄情
3楼-- · 2019-01-10 00:59

Dealing with a very lightweight embedded version of busybox on Linux means many of the traditional commands are not available (bc, printf, dc, perl, python)

echo $((0x2f))
47

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

Credit to Peter Leung for this solution.

查看更多
Fickle 薄情
4楼-- · 2019-01-10 01:02

The error as reported appears when the variables are null (or empty):

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

That could happen because the value given to bc was incorrect. That might well be that bc needs UPPERcase values. It needs BFCA3000, not bfca3000. That is easily fixed in bash, just use the ^^ expansion:

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

That will change the script to this:

#!/bin/bash

var1="bfca3000"
var2="efca3250"

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

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

echo "Diference $var5"

But there is no need to use bc [1], as bash could perform the translation and substraction directly:

#!/bin/bash

var1="bfca3000"
var2="efca3250"

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

echo "Diference $var5"

[1]Note: I am assuming the values could be represented in 64 bit math, as the difference was calculated in bash in your original script. Bash is limited to integers less than ((2**63)-1) if compiled in 64 bits. That will be the only difference with bc which does not have such limit.

查看更多
地球回转人心会变
5楼-- · 2019-01-10 01:07

In dash and other shells, you can use

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

to convert a hexadecimal number to decimal. This is not bash, or ksh, specific.

查看更多
Lonely孤独者°
6楼-- · 2019-01-10 01:10

To convert hex2dec, these are many ways to do it in a shell or a script :

With (beware of the white spaces):

$ echo $(( 16#FF ))
255

with :

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

with :

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

with :

$ printf "%d\n" 0xFF
255

with :

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

with :

$ ruby<<EOF
p "FF".to_i(16).to_s(10)
EOF
"255"

with :

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

with :

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

with :

$ groovy -e 'println Integer.parseInt("FF",16)'
255
查看更多
ら.Afraid
7楼-- · 2019-01-10 01:11

Various tools are available to you from within a shell. Sputnick has given you an excellent overview of your options, based on your initial question. He definitely deserves votes for the time he spent giving you multiple correct answers.

One more that's not on his list:

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

But if all you want to do is subtract, why bother changing the input to base 10?

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

The dc command is "desk calc". It will also take input from stdin, like bc, but instead of using "order of operations", it uses stacking ("reverse Polish") notation. You give it inputs which it adds to a stack, then give it operators that pop items off the stack, and push back on the results.

In the commands above we've got the following:

  • 16i -- tells dc to accept input in base 16 (hexadecimal). Doesn't change output base.
  • BFCA3000 -- your initial number
  • 17FF -- a random hex number I picked to subtract from your initial number
  • - -- take the two numbers we've pushed, and subtract the later one from the earlier one, then push the result back onto the stack
  • p -- print the last item on the stack. This doesn't change the stack, so...
  • 10o -- tells dc to print its output in base "10", but remember that our input numbering scheme is currently hexadecimal, so "10" means "16".
  • p -- print the last item on the stack again ... this time in hex.

You can construct fabulously complex math solutions with dc. It's a good thing to have in your toolbox for shell scripts.

查看更多
登录 后发表回答