Add new element to existing JSON array with jq

前端 未结 3 1330
甜味超标
甜味超标 2020-11-30 01:44

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:

相关标签:
3条回答
  • 2020-11-30 02:11

    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:

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

    0 讨论(0)
  • 2020-11-30 02:15

    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 |= [ _ ] + .
    
    0 讨论(0)
  • 2020-11-30 02:27

    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.

    0 讨论(0)
提交回复
热议问题