I want to append an element to an array in a JSON file using the jq``add
command, but it's not working.
report-2017-01-07.json
file:
{ "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" } ] } }
I am using this command:
$ cat report-2017-01-07.json | jq -s '.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"}' jq: error: syntax error, unexpected '{', expecting $end (Unix shell quoting issues?) at <top-level>, line 1: .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"} jq: 1 compile error
Here's how I want the output to look:
{ "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": "OKKKKKKK", "message": "metadata loaded into iRODS successfullyyyyy" }] } }
jp is a JSON processor for the command line using JSONPath (aka "a simpler jq, and with JSONPath").
jq – a lightweight and flexible CLI processor – can be used as a standalone tool to parse and validate JSON data.
Using JSON Variables in jq If you want to use variables that reference JSON objects, this can be done with the --argsjson option. Using --argjson var object will set the variable $var to object . In the example below we set the $location variable to a JSON object, and nest this object into our results.
jq is a program described as “ sed for JSON data": You can use it to slice and filter and map and transform structured data with the same ease that sed, awk, grep and friends let you play with text.
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"}]
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 |= [ _ ] + .
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With