michelemarcon
michelemarcon

Reputation: 24727

How to manipulate hexadecimal value in Bash?

I have a variable with an hexadecimal value: in this example, a byte with value 0xfe:

echo $MYVAR | hexdump

0000000 0afe
0000002

I want to use this value on my bash script, in particular I need to:

  1. use as a string (echo X$MYVAR should give me Xfe)

  2. increment it, (0xff)

  3. convert back to the original format (I need to save the incremented value for future use)

Maybe it would be easier if I convert it into integer format?

EDIT: here is how I initialize the var:

printf "\xfe" | dd bs=1 of=tempfile seek=8001
MYVAR=`dd if=tempfile skip=8001 count=1 bs=1`

Upvotes: 4

Views: 31330

Answers (2)

Nikita Zlobin
Nikita Zlobin

Reputation: 15

Assuming you stream represents constantly changed numeric parameter, it may be converted by hexdump or od from coreutils. Note, stdbuf is highly recomended for real-time stream processing.

# Print decimal byte values per line
stdbuf -oL hexdump -v -e '1/1 "%u\n"'
# Floating point values
stdbuf -oL hexdump -v -e '1/4 "%f\n"'

Using od from coreutils, for input endianess correction:

# unsigned 8-bit
stdbuf -oL od -v -An -w7 -tu1 --endian=little
# signed 32-bit
stdbuf -oL od -v -An -w4 -tu4 --endian=little
# Float 32-bit
stdbuf -oL od -v -An -w4 -tf4 --endian=little

Unless endianess is issue, hexdump could be more preferable due to good format support - almost like printf:

cat /dev/urandom \
| stdbuf -oL hexdump -v -e '1/4 "%i" 1/4 " %i" 1/4 " %f\n"' \
| stdbuf -oL awk '{ print "("$1" + "$2") * "$3" = ", $1 + $2 * $3 }'

some pointless 8-bit stream math, for example

# Replace the >/dev/null safeguard to actually try it
cat /dev/urandom \
| stdbuf -oL hexdump -e '1/1 " %i" 1/1 " %i" "\n"' \
| {
while read a b; do
    r=$(( (a + b) / 2 ))
    printf "printf \"\%03o\"" $r
done
} | sh >/dev/null

Upvotes: 1

wizard
wizard

Reputation: 1544

To print hex number as string you can

printf 0x%X $MYVAR

to increment it and print it back in hex you can do, for example

printf 0x%X `echo $(( 0xfe + 1 ))`

For "convert back" to the original format I think you mean keep the integer value, in this case you can simply use $MYVAR without format conversion.

Hope this helps,
Regards.

EDIT :
To follow your question editing, I'll add my answer below.

You could set MYVAR in this way:

read dummy MYVAR <<EOF
`dd if=tempfile skip=8001 count=1 bs=1|od -x`
EOF

Now you have hex value of the byte read from file stored in MYVALUE.
You can now print it directly with echo, printf or whatever.

$ echo $MYVAR
00fe

You can perform math on it as said before:

$ printf %X $((0x$MYVAR + 1))
FF

(thanks to fedorqui for the shortest version)

Regards.

Upvotes: 4

Related Questions