You've asked for an awk
command, but consider this generic bash
function, which uses printf
, sed
, and tac
/ tail -r
internally, and works on both BSD (including OSX) and Linux systems:
# SYNOPSIS
# toHexBytes num [numBytes [littleEndian]]
# DESCRIPTION
# Prints the bytes that num is composed of in hex. format separated by commas.
# NUM can be in decimal, hexadecimal, or octal format.
# NUMBYTES specifies the minimum number of *bytes* to output - defaults to *4*.
# Specify 0 to only output as many bytes as needed to represent NUM, '' to
# represent the default when also specifying LITTLEENDIAN.
# By default, the bytes are printed in BIG-endian order; if LITTLEENDIAN is nonzero,
# the bytes are printed in LITTLE-endian order.
# PLATFORM SUPPORT
# BSD and Linux platforms
# EXAMPLES
# toHexBytes 256 # -> '00,00,01,00'
# toHexBytes 256 '' 1 # -> '00,01,00,00'
# toHexBytes 0x100 0 # -> '01,00'
toHexBytes() {
local numIn=$1 numBytes=${2:-4} littleEndian=${3:-0} numHex revCmd
# Convert to hex.
printf -v numHex '%X' "$numIn"
# Determine number of 0s that must be prepended.
padCount=$(( numBytes * 2 - ${#numHex} ))
(( padCount < 0 && ${#numHex} % 2 )) && padCount=1
# Apply 0-padding, if needed.
(( padCount )) && printf -v numHex "%0$(( padCount + ${#numHex} ))X" "0x$numHex"
if (( $littleEndian )); then # LITTLE-endianness
# Determine command to use for reversing lines.
[[ $(command -v tac) ]] && revCmd='tac' || revCmd='tail -r'
# Insert a newline after every 2 digits, except for the last,
# then reverse the resulting lines,
# then read all resulting lines and replace all but the last newline
# with ','.
sed 's/../&\'$'\n''/g; s/\n$//' <<<"$numHex" |
$revCmd |
sed -e ':a' -e '$!{N;ba' -e '}; s/\n/,/g'
else # BIG-endianness
# Insert ',' after every 2 digits, except for the last pair.
sed 's/../&,/g; s/,$//' <<<"$numHex"
fi
}
Applied to your example number:
$ toHexBytes 97254 4 1 # 4 bytes, LITTLE-endian
E6,7B,01,00
$ toHexBytes 97254 # 4 bytes, BIG-endian
00,01,7B,E6