BASH base conversion from decimal to hex

With bash (or any shell, provided the printf command is available (a standard POSIX command often built in the shells)):

printf '%x\n' 85

​​​​​​​​​​​​​​​​​ With zsh, you can also do:

dec=85
hex=$(([##16]dec))

That works for bases from 2 to 36 (with 0-9a-z case insensitive as the digits).

With ksh93, you can use:

dec=85
base54=${ printf %..54 "$dec"; }

Which works for bases from 2 to 64 (with 0-9a-zA-Z@_ as the digits).

With ksh and zsh, there's also:

$ typeset -i34 x=123; echo "$x"
34#3l

Though that's limited to bases up to 36 in ksh88, zsh and pdksh and 64 in ksh93.

Note that all those are limited to the size of the long integers on your system (int's with some shells). For anything bigger, you can use bc or dc.

$ echo 'obase=16; 9999999999999999999999' | bc
21E19E0C9BAB23FFFFF
$ echo '16o 9999999999999999999999 p' | dc
21E19E0C9BAB23FFFFF

With supported bases ranging from 2 to some number required by POSIX to be at least as high as 99. For bases greater than 16, digits greater than 9 are represented as space-separated 0-padded decimal numbers.

$ echo 'obase=30; 123456' | bc
 04 17 05 06

Or same with dc (bc used to be (and still is on some systems) a wrapper around dc):

$ echo 30o123456p | dc
 04 17 05 06

Use printf:

$ printf "%d %x\n" $((16#55)) $((10#85))
85 55

To assign the value to a variable use command substitution:

$ x=$( printf "%x" 85 ) ; echo $x
55

Use the built-in Arithmetic Expansion substitution present in all POSIX compliant shells - which is pretty much universal these days.

$ echo $((0xbc))
188

and

$ hex=dead
$ dec=$((0x$hex))
$ echo $dec
57005

CAUTION: Particularly in the last example the expansion could cause unexpected results - the hex digits in the variable 'hex' have to form a legal hex constant, otherwise potentially obscure error messages happen. e.g. if 'hex' were '0xdead', the arithmetic expansion would become 0x0xdead, which is not interpretable as a constant. Of course, in that case the arithmetic expansion $(($hex)) would do the trick. It is left as an exercise for the reader to create the simple substring processing pattern matching that would remove an optional '0x' prefix.