使用 jq 向现有 JSON 数组添加新元素
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/42245288/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Add new element to existing JSON array with jq
提问by Felipe
I want to append an element to an array in a JSON file using the jq``addcommand, but it's not working.
我想使用该jq``add命令将一个元素附加到 JSON 文件中的数组,但它不起作用。
report-2017-01-07.jsonfile:
report-2017-01-07.json文件:
{
"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"
}]
}
}
回答by Inian
The |= .+part in the filter adds a new element to the existing array. You can use jqwith filter like:
的|= .+在过滤器部分添加到现有阵列的新元素。您可以jq与过滤器一起使用,例如:
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 3and dynamically add a new element, use . | lengthwhich returns the length, which can be used as the next array index, i.e.,
为了避免使用硬编码的长度值3并动态添加新元素,使用. | lengthwhich返回长度,可以用作下一个数组索引,即,
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-playto dry-run your jq-filterand optimize any way you want.
使用jq-play以jq-filter您想要的任何方式试运行和优化。
回答by peak
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:
另一方面,如果(如@NicHuang 所问)要将 JSON 对象添加到数组的开头,则可以使用以下模式:
.data.messages |= [ _ ] + .
回答by pr-pal
Summary: ". +" is your saviour
总结:“.+”是你的救星
Details:
细节:
For adding an entry to a list: You can append [list1] + [list2] (and not [list] + data)
将条目添加到列表:您可以附加 [list1] + [list2](而不是 [list] + 数据)
$ 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:
参考:

