Given following json file.
{
"ver" : "v2.0",
"date" : "11 Jul 2022 21:28 WIB",
"disk" : {},
"network" : {},
"bench" : {}
}
I want to append an object after date
, so the resulting file will be like this.
{
"ver" : "v2.0",
"date" : "11 Jul 2022 21:28 WIB",
"hw": {
"cpu": "intel"
},
"disk" : {},
"network" : {},
"bench" : {}
}
I found this snippet jq -S '. |= . {"hw":{ "cpu" : "intel" }}'
that will append before last object, I tried to modify it a bit but I get jq: error (at main.json:7): Cannot index object with number
.
Can anyone provide me correct query ?
CodePudding user response:
As indicated in they's answer, the ordering of keys don't matter to the reading application
An object is an unsorted collection of keys. The ordering of keys really should not matter to an application reading the JSON document. If you want ordered data, then consider using arrays instead.
But for some reason, if the ordering needs to be guaranteed, you can achieve the same this way
to_entries |
( map(.key == "date") | index(true) ) as $pos |
.[0:$pos 1] [{"key":"hw","value":{"cpu":"intel"}}] .[$pos 1:] |
from_entries
The idea is to convert the JSON records into k/v pairs, find the position of the key named "date"
and then use slice expressions to append the required object after the position and then append back the rest of the pairs.
To pass the JSON as a variable, use the --argjson
flag
jq --argjson n '{"hw":{"cpu":"intel"}}' '
to_entries |
( map(.key == "date") | index(true) ) as $pos |
.[0:$pos 1] ($n|to_entries) .[$pos 1:] |
from_entries' json
Or if the JSON text is stored in a file, e.g. json_file
, use the --slurpfile
option
jq --slurpfile n json_file '
to_entries |
( map(.key == "date") | index(true) ) as $pos |
.[0:$pos 1] ($n[0]|to_entries) .[$pos 1:] |
from_entries' json
If the content is passed over from standard input, use /dev/stdin
as your input file. Can be used with heredocs as well.
echo '{"hw":{"cpu":"intel"}}' |
jq --slurpfile n /dev/stdin '
to_entries |
( map(.key == "date") | index(true) ) as $pos |
.[0:$pos 1] ($n[0]|to_entries) .[$pos 1:] |
from_entries' json