Search code examples
bashawkserial-portxxd

Parse log containing hex character codes using awk or xxd or something


i have a file that looks like this:

.
.
.
    15 02 2013 12:05:07 [DBG] vspd[3327]: VSP   0: RX 452B30303032340D
    15 02 2013 12:05:07 [DBG] vspd[3327]: VSP   0: WX 452B30303032340D

Sniffer log of serial port communication.

How can i automatically translate hex char codes to string?

I tried to use some thing like this:

cat vspd.log | awk -F'(RX|WX)[[:space:]]*' '{print $2}' | awk 'BEGIN { FS = "" }{for (i = 1; i < NF; i = i + 1) a=$i$i+1;printf "%s", a; print}' | xxd -r

But it gives only very partial success, i think i messed something with pipes.

The question is how can i convert

tail -f file.log | awk -F'(RX|WX)[[:space:]]*' '{print $2}'

Into something readable?


Solution

  • You can indeed get there with awk and xxd, here is an example:

    <infile awk -F'(RX|WX)[[:space:]]*' '{ print $2 }' | xxd -p -r | awk 1 RS='\r'
    

    Output:

    E+00024
    E+00024
    

    Old answer

    With GNU awk you can use strtonum() to convert the hexadecimals, e.g.:

    function hex2str(n) {
      s = ""
      for(i=1; i<=length(n)-1; i+=2)
        s = s sprintf("%c", strtonum("0x" substr(n, i, 2)));
      return s
    }
    

    Then you could do the conversion like this:

    { $NF = hex2str($NF) }
    

    Here's a complete example:

    <infile awk ' 
      function hex2str(n) {
        s = ""
        for(i=1; i<=length(n)-1; i+=2)
          s = s sprintf("%c", strtonum("0x" substr(n, i, 2)));
        return s
      }
    
      { $NF = hex2str($NF) }
    
      1
    '
    

    Output:

    15 02 2013 12:05:07 [DBG] vspd[3327]: VSP 0: RX E+00024
    15 02 2013 12:05:07 [DBG] vspd[3327]: VSP 0: WX E+00024