How can I convert hexadecimal values to Binary from the second field to the end
Input:
WS-2 23 345 235
DT-3 45 4A3 000
pp-2 76 300 E4
Output:
WS-2 100011 1101000101 1000110101
DT-3 1000101 10010100011 000
pp-2 1110110 1100000000 11100100
How can I convert hexadecimal values to Binary from the second field to the end
Input:
WS-2 23 345 235
DT-3 45 4A3 000
pp-2 76 300 E4
Output:
WS-2 100011 1101000101 1000110101
DT-3 1000101 10010100011 000
pp-2 1110110 1100000000 11100100
Check "More UNIX and Linux Forum Topics You Might Find Helpful" suggested at the bottom of this thread
I have gone through but could not get help
This works in the bash shell. It is a one-off hack, IMO. perl or some other interpreted language would be more efficient.
#!/bin/bash
#obase.shl - convert to binary from hex
while read rec
do
a=( $rec)
(echo ${a[0]}
echo "ibase=16; obase=2; ${a[1]}" | bc -l
echo "ibase=16; obase=2; ${a[2]}" | bc -l) | tr -s '\n' ' '
echo "ibase=16; obase=2; ${a[3]}" | bc -l
done < infile
$ ./obase.shl
WS-2 100011 1101000101 1000110101
DT-3 1000101 10010100011 0
pp-2 1110110 1100000000 11100100
$
No time left --- I cannot fiddle with the remaining problem : 000 -> output as 000. fix that one yourself.
See this might help you
awk '
function bits2str(bits, data, mask)
{
if (bits == 0)
return "0"
mask = 1
for (; bits != 0; bits = rshift(bits, 1))
data = (and(bits, mask) ? "1" : "0") data
while ((length(data) % 8) != 0)
data = "0" data
return data
}
{for(i=2;i<=NF;i++)$i = bits2str(strtonum("0x"$i))}1' file
0 instead of 000 output is ok
The simplest one-liner I could craft:
( echo ibase=16\; obase=2; awk '$1 = "\""$1"\n\""' OFS=\; file ) | bc | paste - - - -
Regards
Alister
Assuming 4 bits per nibble, I am missing something here.
Binary 23 is 00100011
and 345 is 0000001101000101
and 235 is 0000001000110101
; where are the leading zeros? The OP requires a bit representation not a true hex to binary conversion.
The three zeros is in fact "0000000000000000" as a true hex to binary conversion.
If my assumption is wrong then ignore me...
It's not working on solaris but work on cygwin. how can I make it work on Solaris 10
On Solaris/SunOS
system, change awk
to /usr/xpg4/bin/awk
, /usr/xpg6/bin/awk
, or nawk
, and try
Not working, This is the output:
/usr/xpg4/bin/awk: line 17 (NR=1): variable "" cannot be used as a function
Can you show what you have tried ? what is there in line 17 ?
/usr/xpg4/bin/awk '
function bits2str(bits, data, mask)
{
if (bits == 0)
return "0"
mask = 1
for (; bits != 0; bits = rshift(bits, 1))
data = (and(bits, mask) ? "1" : "0") data
while ((length(data) % 1) != 0)
data = "0" data
return data
}
{for(i=5;i<=NF;i++)$i = bits2str(strtonum("0x"$i))}1' t.log
Okay, copy mystronum
function from here Strtonum Function - The GNU Awk User's Guide, and try
Not working, same message
/usr/xpg4/bin/awk '
function mystrtonum(str, ret, chars, n, i, k, c)
{
if (str ~ /^0[0-7]*$/) {
# octal
n = length(str)
ret = 0
for (i = 1; i <= n; i++) {
c = substr(str, i, 1)
if ((k = index("01234567", c)) > 0)
k-- # adjust for 1-basing in awk
ret = ret * 8 + k
}
} else if (str ~ /^0[xX][[:xdigit:]]+/) {
# hexadecimal
str = substr(str, 3) # lop off leading 0x
n = length(str)
ret = 0
for (i = 1; i <= n; i++) {
c = substr(str, i, 1)
c = tolower(c)
if ((k = index("0123456789", c)) > 0)
k-- # adjust for 1-basing in awk
else if ((k = index("abcdef", c)) > 0)
k += 9
ret = ret * 16 + k
}
} else if (str ~ \
/^[-+]?([0-9]+([.][0-9]*([Ee][0-9]+)?)?|([.][0-9]+([Ee][-+]?[0-9]+)?))$/) {
# decimal number, possibly floating point
ret = str + 0
} else
ret = "NOT-A-NUMBER"
return ret
}
function bits2str(bits, data, mask)
{
if (bits == 0)
return "0"
mask = 1
for (; bits != 0; bits = rshift(bits, 1))
data = (and(bits, mask) ? "1" : "0") data
while ((length(data) % 1) != 0)
data = "0" data
return data
}
{for(i=5;i<=NF;i++)$i = bits2str(mystrtonum("0x"$i))}1' t.log
Hi,
Just for fun, with sed:
$ cat htob.sed
h
s/[^ ]* //
s/0/XXXX/g
s/1/XXXY/g
s/2/XXYX/g
s/3/XXYY/g
s/4/XYXX/g
s/5/XYXY/g
s/6/XYYX/g
s/7/XYYY/g
s/8/YXXX/g
s/9/YXXY/g
s/A/YXYX/g
s/B/YXYY/g
s/C/YYXX/g
s/D/YYXY/g
s/E/YYYX/g
s/F/YYYY/g
y/XY/01/
x
s/ .*//
G
s/\n/ /
s/ 0*1/ 1/g
s/ 0* / 0 /g
s/ 0*$/ 0/g
$ cat filetoconv
WS-2 23 345 235
DT-3 45 4A3 000
pp-2 76 300 E4
$ sed -f htob.sed filetoconv
WS-2 100011 1101000101 1000110101
DT-3 1000101 10010100011 0
pp-2 1110110 1100000000 11100100
Regards.
1993 and later versions of the Korn shell give you some other options. On Solaris 10, /bin/ksh is based on ksh88, but I believe /usr/dt/bin/dtksh should work (although i don't currently have access to a system to verify it).
If the hexadecimal values you're trying to convert can be represented in a long in the programming model used by the shell on your system, the script:
#!/usr/dt/bin/dtksh
while read -A a
do printf '%s' "${a[0]}"
for ((i = 1; i < ${#a[@]}; i++))
do
typeset -i2 b=0x${a}
printf " %s" ${b:2}
done
echo
done < Input
should do what you want. If you have arbitrarily long strings of hexadecimal digits, to convert to binary, I think the following script does what you want:
#!/usr/dt/bin/dtksh
typeset -A b b1
b1['0']='0'; b['0']='0000'
b1['1']='1'; b['1']='0001'
b1['2']='10'; b['2']='0010'
b1['3']='11'; b['3']='0011'
b1['4']='100'; b['4']='0100'
b1['5']='101'; b['5']='0101'
b1['6']='110'; b['6']='0110'
b1['7']='111'; b['7']='0111'
b1['8']='1000'; b['8']='1000'
b1['9']='1001'; b['9']='1001'
b1['A']='1010'; b['A']='1010'
b1['B']='1011'; b['B']='1011'
b1['C']='1100'; b['C']='1100'
b1['D']='1101'; b['D']='1101'
b1['E']='1110'; b['E']='1110'
b1['F']='1111'; b['F']='1111'
b1['a']='1010'; b['a']='1010'
b1['b']='1011'; b['b']='1011'
b1['c']='1100'; b['c']='1100'
b1['d']='1101'; b['d']='1101'
b1['e']='1110'; b['e']='1110'
b1['f']='1111'; b['f']='1111'
while read -A a
do printf '%s' "${a[0]}"
for ((i = 1; i < ${#a[@]}; i++))
do printf ' %s' "${b1[${a[$i]:0:1}]}"
for ((j = 1; j < ${#a[$i]}; j++))
do printf '%s' "${b[${a[$i]:$j:1}]}"
done
done
echo
done < Input
I used the file Input
containing:
WS-2 23 345 235
DT-3 45 4A3 000
pp-2 76 300 E4
hex 10 21 32 43 54 65 76 87 98 A9 BA CB DC ED FE 0F AbCdEf1
hex2long 1234567890ABCDEFabcdef1234567890abcdefABCDEF
as a test case using /bin/ksh on OS X. The values show in red produced different results from these two scripts. The output produced by the 1st script above is:
WS-2 100011 1101000101 1000110101
DT-3 1000101 10010100011 0
pp-2 1110110 1100000000 11100100
hex 10000 100001 110010 1000011 1010100 1100101 1110110 10000111 10011000 10101001 10111010 11001011 11011100 11101101 11111110 1111 1010101111001101111011110001
hex2long 0
and the output produced by the 2nd script above is:
WS-2 100011 1101000101 1000110101
DT-3 1000101 10010100011 000000000
pp-2 1110110 1100000000 11100100
hex 10000 100001 110010 1000011 1010100 1100101 1110110 10000111 10011000 10101001 10111010 11001011 11011100 11101101 11111110 01111 1010101111001101111011110001
hex2long 10010001101000101011001111000100100001010101111001101111011111010101111001101111011110001001000110100010101100111100010010000101010111100110111101111101010111100110111101111