Home > Back-end >  Convert a raw data to json using awk
Convert a raw data to json using awk

Time:11-16

I am having input data as below, I need to phrase it to be a JSON. Working on a legacy node and don't have jq(mentioning in advance)

e1
status: up
temp: 140
alarm: none
e2
status: down
temp: 141
alarm: none
e3
status: up
temp: 144
alarm: 2
e4
status: up
temp: 65
alarm: 2
region: us-east

I was hoping to get the following output:

{"e1" : { "status": "up", "temp": "140", "alarm": "none"}}
{"e2" : { "status": "down", "temp": "141", "alarm": "none"}}
{"e3" : { "status": "up", "temp": "144", "alarm": "2"}}
{"e4" : { "status": "up", "temp": "65", "alarm": "2", "region": "us-east"}}

I tried to make a workaround using awk but not able to combine the results by key:

awk '!/:/{node=$0} /:/{print "{\"",node,"\"}",":", "{", $0 ,"}"  }' inputfile
{" e1 "} : { status: up }
{" e1 "} : { temp: 140 }
{" e1 "} : { alarm: none }
{" e3 "} : { status: down }
{" e3 "} : { temp: 141 }
{" e3 "} : { alarm: none }
{" e3 "} : { status: up }
{" e3 "} : { temp: 144 }
{" e3 "} : { alarm: 2 }

Any suggestions ?

CodePudding user response:

One awk idea where we append consecutive input lines together (via the awk/out variable):

awk -F':' '                                           # input field delimiter is ":"
NF==1 { if (out)                                      # if number of ":" delimited fields is 1 then we are starting a new block, and if "out" is non-empty then ...
           print out "}}"                             # print the previous block to stdout and ...
        out="{\"" $1 "\" : { "                        # start building a new "out"
        sep=""
        next
      }
      { gsub(/^[ ] /,"",$2)                           # strip leading spaces from 2nd field
        out=out sep "\"" $1 "\": \"" $2 "\""
        sep=", "
      }
END   { if (out)                                      # if non-empty then ...
           print out "}}"                             # flush last "out" to stdout
      }
' inputfile

This generates:

{"e1" : { "status": "up", "temp": "140", "alarm": "none"}}
{"e2" : { "status": "down", "temp": "141", "alarm": "none"}}
{"e3" : { "status": "up", "temp": "144", "alarm": "2"}}
{"e4" : { "status": "up", "temp": "65", "alarm": "2", "region": "us-east"}}

CodePudding user response:

can do this:

jq --raw-input '
  reduce ((., inputs) | scan("([^:] )(: (.*))?")) as $m ({obj: {}, key: null};
    if $m[1] == null
      then .key = $m[0] | .obj[.key] = {}
      else .obj[.key]  = {($m[0]): $m[2]}
    end
  )
  | .obj
' inputfile
{
  "e1": {
    "status": "up",
    "temp": "140",
    "alarm": "none"
  },
  "e2": {
    "status": "down",
    "temp": "141",
    "alarm": "none"
  },
  "e3": {
    "status": "up",
    "temp": "144",
    "alarm": "2"
  },
  "e4": {
    "status": "up",
    "temp": "65",
    "alarm": "2",
    "region": "us-east"
  }
}
  • Related