Add new element to existing JSON array with jq
The |= .+
part in the filter adds a new element to the existing array. You can use jq
with filter like:
jq '.data.messages[3] |= . + {"date": "2010-01-07T19:55:99.999Z", "xml": "xml_samplesheet_2017_01_07_run_09.xml", "status": "OKKK", "message": "metadata loaded into iRODS successfullyyyyy"}' inputJson
To avoid using the hardcoded length value 3
and dynamically add a new element, use . | length
which returns the length, which can be used as the next array index, i.e.,
jq '.data.messages[.data.messages| length] |= . + {"date": "2010-01-07T19:55:99.999Z", "xml": "xml_samplesheet_2017_01_07_run_09.xml", "status": "OKKK", "message": "metadata loaded into iRODS successfullyyyyy"}' inputJson
(or) as per peak's suggestion in the comments, using the +=
operator alone
jq '.data.messages += [{"date": "2010-01-07T19:55:99.999Z", "xml": "xml_samplesheet_2017_01_07_run_09.xml", "status": "OKKK", "message": "metadata loaded into iRODS successfullyyyyy"}]'
which produces the output you need:
{ "report": "1.0", "data": { "date": "2010-01-07", "messages": [ { "date": "2010-01-07T19:58:42.949Z", "xml": "xml_samplesheet_2017_01_07_run_09.xml", "status": "OK", "message": "metadata loaded into iRODS successfully" }, { "date": "2010-01-07T20:22:46.949Z", "xml": "xml_samplesheet_2017_01_07_run_09.xml", "status": "NOK", "message": "metadata duplicated into iRODS" }, { "date": "2010-01-07T22:11:55.949Z", "xml": "xml_samplesheet_2017_01_07_run_09.xml", "status": "NOK", "message": "metadata was not validated by XSD schema" }, { "date": "2010-01-07T19:55:99.999Z", "xml": "xml_samplesheet_2017_01_07_run_09.xml", "status": "OKKK", "message": "metadata loaded into iRODS successfullyyyyy" } ] }}
Use jq-play to dry-run your jq-filter
and optimize any way you want.
Rather than using |=
, consider using +=
:
.data.messages += [{"date": "2010-01-07T19:55:99.999Z", "xml": "xml_samplesheet_2017_01_07_run_09.xml", "status": "OKKK", "message": "metadata loaded into iRODS successfullyyyyy"}]
Prepend
On the other hand, if (as @NicHuang asked) you want to add the JSON object to the beginning of the array, you could use the pattern:
.data.messages |= [ _ ] + .
Summary: ". +" is your saviour
Details:
For adding an entry to a list: You can append [list1] + [list2] (and not [list] + data)
$ echo '[ "data1" ]' | jq '. + [ "data2" ]'[ "data1", "data2"]$ echo '[ {"key1": "value1"} ]' | jq '. + [{"key2": "value2"}]'[ { "key1": "value1" }, { "key2": "value2" }]
For adding a key/value to a dictionary:
$ echo '{"key1": "value1"}' | jq '. + {"key2": "value2"}'{ "key1": "value1", "key2": "value2"}
References: