Hexadecimal To Decimal in Shell Script

194,636

Solution 1

To convert from hex to decimal, there are many ways to do it in the shell or with an external program:

With :

$ 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 -e 'p "FF".to_i(16)'
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

Solution 2

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.

Solution 3

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

echo $((16#FF))
255

Solution 4

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.

Solution 5

In dash and other shells, you can use

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

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

Share:
194,636

Related videos on Youtube

VenkateshJN
Author by

VenkateshJN

Actively looking for full-time opportunities in the fields of Software Development, Data Mining &amp; Machine Learning. Would like to work on interesting and challenging projects that would leverage my skills and provide me satisfaction of being useful to the society.

Updated on April 30, 2021

Comments

  • VenkateshJN
    VenkateshJN about 3 years

    Can someone help me 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]
    

    When executing, I get this error:

    Line 48: -: syntax error: operand expected (error token is "-")
    
  • user1527227
    user1527227 almost 10 years
    What does the # symbol mean? Are there any other applications or documentation to read more about its use?
  • Tomás Fox
    Tomás Fox almost 10 years
    It is mentioned here: link . At the end of section 6.5 it says: "...numbers take the form [base#]n, where the optional base is a decimal number between 2 and 64 representing the arithmetic base, and n is a number in that base. If base# is omitted, then base 10 is used. The digits greater than 9 are represented by the lowercase letters, the uppercase letters, ‘@’, and ‘_’, in that order. If base is less than or equal to 36, lowercase and uppercase letters may be used interchangeably to represent numbers between 10 and 35."
  • Ciro Santilli OurBigBook.com
    Ciro Santilli OurBigBook.com about 9 years
    Is the printf solution POSIX? If yes, it's the best :)
  • Ruslan
    Ruslan over 7 years
    In bash you can also use $((0xff)), i.e. with C-like hex prefix instead of 16#, although N# is clearly more general.
  • roblogic
    roblogic about 6 years
    OK but beware of integer overflow error, e.g. echo $((0x077E9F2DBF49D100001)) overflows the 64-biit integer limit of 2^64. bc handles this properly
  • roblogic
    roblogic about 6 years
    The first bash example is susceptible to integer overflow error, e.g. echo $((077E9F2DBF49D100001#FF)) overflows the 64-bit integer limit of 2^64. bc handles this properly.
  • lashgar
    lashgar over 5 years
    e.g. printf "%d" 0xff
  • Michael Shigorin
    Michael Shigorin over 5 years
    lspci to xorg.conf PCI ID transform, just in case: lspci -d ::0300 | cut -f1 -d' ' | ( IFS=":." read b d f; printf "PCI:%02d:%02d:%02d\n" 0x$b 0x$d 0x$f )
  • Gilles Quenot
    Gilles Quenot about 3 years
    This syntax is discouraged by Chet Ramey himself. Use $((0x3f))
  • Jeroen Wiert Pluimers
    Jeroen Wiert Pluimers about 3 years
    Indeed echo has limitations and bc solves them, but Busybox does currently not have bc among the applets. Hopefully it does in the future.
  • Jeroen Wiert Pluimers
    Jeroen Wiert Pluimers about 3 years
    The solution by @hinekyle using echo $((0x2f)) does work with dash (tested on "BusyBox v1.29.3 (2019-05-21 15:22:06 PDT) multi-call binary." that is part of VMware ESXi 6.5 update 3).
  • frido
    frido about 3 years
    Also solution for unsigned 64-bit values with printf "%u" 0xff
  • Amruth A
    Amruth A almost 3 years
    syntax error in expression (error token is "3")
  • user2240578
    user2240578 almost 2 years
    bash ~ ➜ node <<< "console.log(0x1f)" 31