NAWK conversion of hexadecimal input to decimal output via printf, I am close I can feel it

I have searched and the answers I have found thus far have led me to this point, so I feel I am just about there.

I am trying to convert a column of hexadecimal to decimal values so that I can filter out via grep just the data I want. I was able to pull my original 3 character hex value and append 0x to the front but the printf statement seems not to work to convert it to decimal. I dumped my output to a file and have been trying to get it to convert so I can proceed on.

Here are the last lines snipped from my file, as it it large:

0x0C0,###0,33,6291
0x011,###1,59,0
0x009,###0,59,362147
0x011,###2,59,260
0x00E,###2,59,1051
0x008,###1,33,0
0x034,###2,59,0
0x001,###3,59,208
0x00E,###2,33,52
0x034,###2,33,0
0x00F,###1,59,0
0x009,###0,33,33022

From the shell prompt I tried:

printf  "%d\n" 0x03E

and get the proper output:

62

If I type:

cat <file>|nawk -F, '{printf "%d\n" , $1}'

I get nothing but zeroes as output:

0
0
0
0
0
0
0
0
0

I tested via:

cat <file>|nawk -F, '{$1,"     ""%d\n",$1}'

and my output has the correct output from $1, but "%d\n" won't output the decimal equivalent:

0x0C0     0
0x011     0
0x009     0
0x011     0
0x00E     0
0x008     0
0x034     0
0x001     0
0x00E     0
0x034     0
0x00F     0
0x009     0

So what am I missing? I have had it suggested that printf is different in awk than in the shell but that seemed wrong from what I read.

Please post what Operating System and version you are running and what Shell you have.
I may not be able to help with the solution, but this basic information will help other posters.

Re-reading the original post it is hard to work out what you are trying to achieve.
Please post sample input data, sample matching output data and a brief description of the process.

SunOS, looks like 5.10? Running on a Sparc Netra-240. Let me clean up my post to clarify input > process > output. Thank you.

Oh and I am in zsh for editing but I can't guarantee what a user will be in so I try to keep it good for basic sh.

awk/nawk don't have native support for hexadecimal.

function parsehex(V,OUT)
{
    if(V ~ /^0x/)  V=substr(V,3);

    for(N=1; N<=length(V); N++)
        OUT=(OUT*16) + H[substr(V, N, 1)]

    return(OUT)
}

BEGIN { for(N=0; N<16; N++)
        {  H[sprintf("%x",N)]=N; H[sprintf("%X",N)]=N } }

{ print parsehex($1) }
1 Like

Thank you for the reply, I am glad it was awk/nawk and not me this time. :slight_smile: Now to take your code and figure out how to make it work for me!

Lateral thought.
Have you considered converting the search number in question to matching format hexadecimal and then using grep rather than converting all the hexadecimal values in the large file to decimal?

1 Like

Heh, that is actually what I have been pondering pretty heavily as an alternative actually. :slight_smile:

My suggestion that end users learn hexadecimal before touching my script was denied, sadly.

Users can enter query in decimal. You just need to change the decimal to a suitable matching hexadecimal format.

I am looking at bc now, converting dec input to hex may actually be easier since I am completely untrained and new at this. I can strip off the 0x (actually just pull out the part where I added it) then make the decimal input 3 characters before conversion.

Can't you just use shell?

while IFS=, read val x; do 
  printf "%s\t%d\n" "$val" "$val"
done < infile
0x0C0	192
0x011	17
0x009	9
0x011	17
0x00E	14
0x008	8
0x034	52
0x001	1
0x00E	14
0x034	52
0x00F	15
0x009	9

Just to provide resolution, I have gone with the convert the decimal input option and after another day of learing this is what I came up with:

 
#!/bin/bash
echo "Site number:"
read decsite
hexsite=`echo "obase=16;$decsite"|bc`
hexfix=$(printf "%.3X" 0x$hexsite)
 

This gives me the 3-character hex value I need to GREP out the information I want going forward and lets the user just enter any old decimal digits.

Thank you for all your help people!

My next thing is to see if I can get it to work in sh instead of bash for universal portability.