Converting hex to ascii/decimal

I am writing a bash script to do some parsing on a log and I am running into a problem when it comes to converting only certain sections of the file from hex to ascii or hex to decimal.

Data Example:

The hex values after Hardware and SW Version I need to convert from Hex to ASCII and the Errors, Full, Test values I need to convert from hex to decimal.

The output should look like the following:

Thanks for any help!

$
$ cat xverter
#! /usr/bin/bash

# convert from hex to ascii
sample=" 38 30 30 30"
sample=${sample// /\\x}
sample="$sample\\n"
printf "$sample"

#
# convert from base 16 to base 10

hex=76
((dec=0X$hex))
echo $dec

exit 0
$
$
$ ./xverter
8000
118
$
1 Like

Thanks , but how would I go about searching for the line and then converting whatever is in between the brackets because its not going to be the same values every time.

Perhaps id have to search for Hardware and then take whatever is in between the brackets set as a variable and then use the above code for the conversion?

Exactly. And you will need to ensure that you have exactly one space before each hex value for the hex to ascii conversion. And no spaces at all for the hex to decimal conversion.

Ruby(1.9+)

#!/usr/bin/env ruby 
File.open("file").each do|line|
    if line =~ /^(SW|Hardware)|Error|Test|Full/i
        toconv = line.scan(/\[(.*?)\]/)[0][0]
        if line =~ /SW|Hardware/
            toconv = toconv.split.map{|x|x.hex.chr}.join
        else
            toconv = toconv.split.map{|x|x.hex}.join
        end
        line.gsub!( /(.*\[)(.*)(\].*)/ , "\\1#{toconv}\\3" )
    end
    puts line
end

Test run:

$ ruby myconvert.rb
------------
ip = 10.2.3.4
------------
Hardware= [8000]
Errors= [0161]
Full= [99]
SW Version= [1.8.1.109]
Test= [118]
------------
ip = 10.2.3.8
------------
Hardware= [4000]
Errors= [0161]
Full= [69]
SW Version= [1.8.1.109]
Test= [118]

A bit verbose, but......
nawk -f shift.awk myFile

shift.awk:

BEGIN {
  FS="([[]|[]])"
}
function hex2dec(h,  i,x,v){
  h=tolower(h);sub(/^0x/,"",h)
  for(i=1;i<=length(h);++i){
    x=index("0123456789abcdef",substr(h,i,1))
    v=(16*v)+x-1
  }
  return v
}

function hex2str(h) {
  printf("%c", hex2dec(h))
}
/^(--|ip)/ {print; next}

/^(Hardware|SW Version)=/ {
  printf("%s",$1 "[")
  n=split($2, vA,OFS)
  for(i=1;i<=n;i++)
     printf("%c%s", hex2str(vA), (i==n)? "]"ORS:"")
  next
}
{
  printf("%s",$1 "[")
  n=split($2, vA,OFS)
  for(i=1;i<=n;i++)
     printf("%d%s", hex2dec(vA), (i==n)? "]"ORS:"")
}
1 Like

Thanks but I dont have ruby installed so I cant test that code out.

trying to finish it up with awk and sed atm, will post if I can get it working.

---------- Post updated at 10:38 AM ---------- Previous update was at 09:57 AM ----------

Awesome vgersh99! I tweaked a few things to match my actual log file and it works perfectly.

Im not to familiar with using awk with bash scripts though, how do I go about combining that piece of awk code with the rest of my bash script? I keep getting errors when I put awk inside the script.

#!/bin/bash

......
......

nawk '
 <here comes the copy/paste of shift.awk>
' myFile

....
....
1 Like

Bash (and a number of other shells) has builtin support for different numeral radices

For example:

$ hex=76
$ echo "Decimal equivalent is: $(( 16#76 ))"
Decimal equivalent is: 118
$ echo "Octal equivalent is: $(( 8#76 ))"
Octal equivalent is: 62
$

Ok so new problem. Everything was looking ok when I output the data on the screen, But once I actual open or view the output file I get ^@ after every ASCII character. Any ideas? I tried removing with sed and tr but no luck. tr just reverts it back to its hex form

do cat -vet myFile and post the results (using code tags).
Posting your modified script would help as well...

1 Like

---------- Post updated at 02:33 PM ---------- Previous update was at 02:33 PM ----------

This was output after running

no, I meant cat -vet ORIGINALfile .
Also please post your modified script.

1 Like

Modified script:

Output after running

on original data file Sample.log

---------- Post updated at 02:53 PM ---------- Previous update was at 02:48 PM ----------

Sorry here is with code tags:

Hm....... Strange works fine here (Solaris).
Try changing

n=split($2, vA,OFS)

to

n=split($2, vA," ")

BTW, what OS are you on?

1 Like

tried some tr stuff again and got it to work this time

used

tr "\000" " " < inputFile > outputFile

Thank you so much for the help and patience!

---------- Post updated at 03:11 PM ---------- Previous update was at 03:06 PM ----------

Actually should of done this first time, just deleted the null character rather than replace it

tr -d "\000" <input > output

Hmmm... strange printf implementation of your awk...

Change

/^(Hardware|SW Version)=/ {
  printf("%s",$1 "[")
  n=split($2, vA,OFS)
  for(i=1;i<=n;i++)
     printf("%c%s", hex2str(vA), (i==n)? "]"ORS:"")
  next
}

to this:

/^(Hardware|SW Version)=/ {
  printf("%s",$1 "[")
  n=split($2, vA,OFS)
  for(i=1;i<=n;i++)
     printf("%c", hex2str(vA))
  print "]" ORS
  next
}

1 Like