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]
CodePudding user response:
Here are some more approaches which all work well with jq 1.5:
- using
capture
andfrom_entries
jq -Rn '[inputs | capture("(?<key>\\S )\\s (?<value>. )")] | from_entries'
- using
splits
andreduce
jq -Rn 'reduce (inputs | [splits("\\s ")]) as [$k,$v] ({}; .[$k] = $v)'
- using
splits
andadd
jq -Rn '[inputs | [splits("\\s ")] as [$k, $v] | {($k): $v}] | add'