5

I'm adding a property to a JSON string with

result=$(jq -c ".docs[$docIndex] + { \"value\": \"value\" }"<<<"$fileContent")

Where the JSON inside $fileContent is

{
    "docs": [
        {
            "id": 123
        },
        {
            "id": 456
        },
        {
            "id": 678
        },
        ...
    ]
}

But what is inside $resultafter my operation is {"id:123", "value":"value"}. How do I return the full output? What I would like is that result becomes

{
    "docs": [
        {
            "id": 123,
            "value": "value"
        },
        {
            "id": 456
        },
        {
            "id": 678
        },
        ...
    ]
}
Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
MHogge
  • 237

1 Answers1

6

jq is fundamentally a filter, so .docs[0] limits the data that the rest of the script has available to what it selected. At the end of the program, whatever's in the stream is outputted. Thus the + { ... } only sees the one object, and its output is used as the output of the whole program.

If instead you want to modify one of the elements you've selected, use +=, which is an alias for the update-assignment operator |= . + ...:

jq '.docs[1] += { "value": "value" }' < ...

You could equivalently write the desugared

jq '.docs[1] |= . + { "value": "value" }' < ...

In either case, it replaces the current value (what . was when you started) with the result of applying the change you describe to the element(s) you selected. That new value carries on through the pipeline, in this case immediately to the output stage.

Michael Homer
  • 76,565