Home > Mobile >  JQ How to update selected objects while also printing out the entire JSON document
JQ How to update selected objects while also printing out the entire JSON document

Time:03-18

I'm trying to simply update an array, while also printing out the full JSON body. Whenever I update the array, I can only output the JSON object that Im updating rather than printing the entire JSON document, plus the updates.

Command:

array='{"uid": "foo123" }, {"uid": "bar123"}'
t=Test

jq --arg title "$t" --arg array "[$array]" \
  '. | select(.data[].title == $title) | .alert.notifications = ($array | fromjson)'

Input:

{
  "data": [
    {
      "alert": {
        "notifications": [
          {
            "uid": "foo"
          },
          {
            "uid": "bar"
          }
        ]
      },
      "title": "Test"
    },
    {
      "alert": {
        "notifications": [
          {
            "uid": "foo1"
          },
          {
            "uid": "bar1"
          }
        ]
      },
      "title": "Test2"
    }
  ]
}

Undesired Output:

{
  "data": [
    {
      "alert": {
        "notifications": [
          {
            "uid": "foo"
          },
          {
            "uid": "bar"
          }
        ]
      },
      "title": "Test"
    },
    {
      "alert": {
        "notifications": [
          {
            "uid": "foo1"
          },
          {
            "uid": "bar1"
          }
        ]
      },
      "title": "Test2"
    }
  ],
  "alert": {
    "notifications": [
      {
        "uid": "foo123"
      },
      {
        "uid": "bar123"
      }
    ]
  }
}

Desired Output:

{
  "data": [
    {
      "alert": {
        "notifications": [
          {
            "uid": "foo123"
          },
          {
            "uid": "bar123"
          }
        ]
      },
      "title": "Test"
    },
    {
      "alert": {
        "notifications": [
          {
            "uid": "foo1"
          },
          {
            "uid": "bar1"
          }
        ]
      },
      "title": "Test2"
    }
  ]
}

I have tried a few different scenarios and it the closest I have come is the undesired output. Any help would be greatly appreciated!

Thanks,

CodePudding user response:

Try updating |= the data field with a map:

array='{"uid": "foo123" }, {"uid": "bar123"}'
t=Test

jq --arg title "$t" --arg array "[$array]" \
  '.data |= map(select(.title == $title).alert.notifications = ($array | fromjson))'

Alternatively, wrap the LHS of the assigment into parentheses to retain the context:

array='{"uid": "foo123" }, {"uid": "bar123"}'
t=Test

jq --arg title "$t" --arg array "[$array]" \
  '(.data[] | select(.title == $title).alert.notifications) = ($array | fromjson)'

In any case, there's no need for .|.

  • Related