使用jq将新元素添加到现有JSON数组

时间:2017-02-15 09:24:33

标签: json bash jq

我有一个json文件,我想在其上附加一个新的对象数组。我正在尝试使用jq命令行。正如我在互联网上看到的那样,这个命令就是这样做的,不仅仅是对Json文件中的查询对象。但我无法弄清楚如何在jq上使用ADD命令。 我的Json文件是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"
         }
      ]
   }
}

我正在使用以下命令>>

$ 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

我已经尝试过另一个命令组合,但我总是以错误编译结束。有什么暗示吗? 谢谢!

输出必须类似于&gt;&gt;

{
    "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"
        }]
    }
}

3 个答案:

答案 0 :(得分:41)

过滤器中的|= .+部分会向现有数组添加新元素。您可以将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

为避免使用硬编码长度值3并动态添加新元素,请使用返回长度的. | length,该长度可用作下一个数组索引,即

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

(或)根据评论中的峰值建议,仅使用+=运算符

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"}]'

根据需要生成输出。

{
  "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"
      }
    ]
  }
}

使用jq-play来干燥您的jq-filter并优化您想要的任何方式。

答案 1 :(得分:25)

不是在这里使用|=,而是使用+=

要好得多
.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"}]

前置

另一方面,如果(如@NicHuang所说)你想将JSON对象添加到数组的开头,你可以使用模式:

 .data.messages |= [ _ ] + .

答案 2 :(得分:1)

摘要:“。+”是您的救星

详细信息:

要在列表中添加条目:您可以附加[list1] + [list2](而不是[list] +数据)

$ echo '[ "data1" ]' | jq '. + [ "data2" ]'
[
  "data1",
  "data2"
]

$ echo '[ {"key1": "value1"} ]' | jq '. + [{"key2": "value2"}]'
[
  {
    "key1": "value1"
  },
  {
    "key2": "value2"
  }
]

用于向字典添加键/值:

$ echo '{"key1": "value1"}' | jq '. + {"key2": "value2"}'
{
  "key1": "value1",
  "key2": "value2"
}

参考文献:

https://gist.github.com/joar/776b7d176196592ed5d8