Home > Back-end >  JQ append object after specific object
JQ append object after specific object

Time:07-12

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.

demo - jqplay


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
  • Related