skip to Main Content

I want to append some content by using shell script.
I have a JSON file test.json as below.

{
  "reference": "Json Test",
  "title": {
    "a": "Json Test"
  },
  "components": [
    {
      "reference": "Json Test",
      "type": "panel",
      "content": [
        {
          "link": "abc/123",
          "label": {
            "a": "for test 123 - a",
            "b": "for test 123 - b"
          }
        },
        {
          "link": "abc/456",
          "label": {
            "a": "for test 456 - a",
            "b": "for test 456 - b"
          }
        },
        {
          "link": "abc/789",
          "label": {
            "a": "for test 789 - a",
            "b": "for test 789 - b"
          }
        }
      ]
    }
  ]
}

I want to append the content and output as following by using shell script (*.sh) How can I achieve this ?

{
  "reference": "Json Test",
  "title": {
    "a": "Json Test"
  },
  "components": [
    {
      "reference": "Json Test",
      "type": "panel",
      "content": [
        {
          "link": "abc/123",
          "label": {
            "a": "for test 123 - a",
            "b": "for test 123 - b"
          }
        },
        {
          "link": "abc/101112",
          "label": {
            "a": "for test 101112 - a",
            "b": "for test 101112 - b"
          }
        },
        {
          "link": "abc/456",
          "label": {
            "a": "for test 456 - a",
            "b": "for test 456 - b"
          }
        },
        {
          "link": "abc/789",
          "label": {
            "a": "for test 789 - a",
            "b": "for test 789 - b"
          }
        }
      ]
    }
  ]
}

I tried to access the index and add some test string, the below command will replace the original data.

jq '.components[].content[1] + { "link" : "test" } ' test.json

2

Answers


  1. You can use the slice filter to extract the head and the tail of the array, then use + to concatenate head + the new object + the tail. Finally, use update-assignment |= to modify the array:

    .components[].content |= .[0:1] + [{ link: "test" }] + .[1:]
    

    If you are planning on using this more often, consider defining a reusable function:

    def splice($at; $obj): .[0:$at] + [$obj] + .[$at:]; 
    
    .components[].content |= splice(1; {link: "test"})
    
    Login or Signup to reply.
  2. Grab the empty sub-array at position 1 (slicing either by start and end position .[1:1], or by start position and length .[1:][:0]), and assign to it your insert value formatted as (single-element) array [{"link": "test"}] (as you are assigning to an array after all – add more items to it if you want to add all of them at once). This looks almost like your original attempt:

    jq '.components[].content[1:1] = [{"link": "test"}]' test.json
    

    For convenience, you can also turn this into an insertAt function:

    def insertAt($pos; $val): .[$pos:$pos] = [$val];
    
    .components[].content |= insertAt(1; {"link": "test"})
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search