Home > Mobile >  Using jq to transform lines of key-values to json
Using jq to transform lines of key-values to json

Time:04-28

I am looking to transform a set of rows that are key value (space seperated) to JSON. I am hoping to use jq-1.5 for this:

local.location.altitude   3.0
local.location.latitude   40.025495
local.location.longitude  -74.312501
local.orientation.pitch   0.0
local.orientation.roll    0.0
local.orientation.yaw     0.0
local.velocity.azimuth    0.0
local.velocity.elevation  0.0
local.velocity.magnitude  0.0

To

{
  "local.location.altitude": "3.0",
  "local.location.latitude": "40.025495",
  "local.location.longitude": "-74.312501",
  "local.orientation.pitch": "0.0",
  "local.orientation.roll": "0.0",
  "local.orientation.yaw": "0.0",
  "local.velocity.azimuth": "0.0",
  "local.velocity.elevation": "0.0",
  "local.velocity.magnitude": "0.0"
}

I am trying commands like:

./get-data | jq -R 'splits("\\s ")'
./get-data | jq -R 'splits("\\s ")|{ a : .[0], b : .[1] }

But unable to make it work. I feel I am close. Anyone know how to go from {{key}} {{val}} to {"key": "value"}?

CodePudding user response:

Use the raw input mode along with null input mode -n, so that you can get the whole input by [inputs] and further split by a regular expression indicating one or more whitespace characters.

The split() method can take a second argument to indicate any possible flags to provide.

Also inside the object formation, use (..) to generate key names.

jq -nR '[inputs] | map(split("\\s "; "")) | map({(.[0]): .[1]}) | add'

If you want the values in numeric form, rather than as strings use (.[1] | tonumber) instead of just .[1]

jqplay demo

CodePudding user response:

Here are some more approaches which all work well with jq 1.5:

  • using capture and from_entries
jq -Rn '[inputs | capture("(?<key>\\S )\\s (?<value>. )")] | from_entries' 

Demo

  • using splits and reduce
jq -Rn 'reduce (inputs | [splits("\\s ")]) as [$k,$v] ({}; .[$k] = $v)'

Demo

  • using splits and add
jq -Rn '[inputs | [splits("\\s ")] as [$k, $v] | {($k): $v}] | add'

Demo

  • Related