1

i have a JSON file

js.json

{
  "id": "json",
  "description": "test",
  "packages": [
    {
      "Group": "group1",
      "Name": "name1",
      "Version": "1.0.0"
    },
    {
      "Group": "group2",
      "Name": "name2",
      "Version": "1.0.0"
    },
    {
      "Group": "group3",
      "Name": "name3",
      "Version": "1.0.0"
    },
    {
      "Group": "group5",
      "Name": "name5",
      "Version": "1.0.0"
    }
  ]
}

It has 4 elements in the .packages array. I want to add a fifth element "group4" to the array to get

{
  "id": "json",
  "description": "test",
  "packages": [
    {
      "Group": "group1",
      "Name": "name1",
      "Version": "1.0.0"
    },
    {
      "Group": "group2",
      "Name": "name2",
      "Version": "1.0.0"
    },
    {
      "Group": "group3",
      "Name": "name3",
      "Version": "1.0.0"
    },
    {
      "Group": "group4",
      "Name": "name4",
      "Version": "1.0.0"
    },
    {
      "Group": "group5",
      "Name": "name5",
      "Version": "1.0.0"
    }
  ]
}

if i'm use

jq '.packages[3] |= . + {"Group":"group4", "Name":"name4", "Version":"1.0.0"}' jq.json 
{
  "id": "json",
  "description": "test",
  "packages": [
    {
      "Group": "group1",
      "Name": "name1",
      "Version": "1.0.0"
    },
    {
      "Group": "group2",
      "Name": "name2",
      "Version": "1.0.0"
    },
    {
      "Group": "group3",
      "Name": "name3",
      "Version": "1.0.0"
    },
    {
      "Group": "group4",
      "Name": "name4",
      "Version": "1.0.0"
    }
  ]
}

And i'm lost group5 element. Is it possible to add an item without losing the previous one? I understand that I can save the output of lost indexes and insert them with the new index, but this seems wrong

Barbaros Özhan
  • 59,113
  • 10
  • 31
  • 55
Mateo Neo
  • 81
  • 6
  • Are you trying to add an element *to the middle* of the array, or just to the end? If you're just trying to add it at the end, see ["Add new element to existing JSON array with jq"](https://stackoverflow.com/questions/42245288/add-new-element-to-existing-json-array-with-jq). If you're trying to insert it in the middle, see ["How to insert element into array with jq"](https://stackoverflow.com/questions/66428658/how-to-insert-element-into-array-with-jq) and ["Add JSON Object at specific location"](https://stackoverflow.com/questions/59629569/add-json-object-at-specific-location). – Gordon Davisson Dec 08 '21 at 10:52

3 Answers3

3

Update |= the .packages field by redifining it as a new array consisting of the first three elements .[:3], the new one [{…}] and the the rest .[3:]. Technically, we are constructing an array by piecing three arrays together +.

jq '.packages |= .[:3] + [{Group: "group4", Name: "name4", Version: "1.0.0"}] + .[3:]'
{
  "id": "json",
  "description": "test",
  "packages": [
    {
      "Group": "group1",
      "Name": "name1",
      "Version": "1.0.0"
    },
    {
      "Group": "group2",
      "Name": "name2",
      "Version": "1.0.0"
    },
    {
      "Group": "group3",
      "Name": "name3",
      "Version": "1.0.0"
    },
    {
      "Group": "group4",
      "Name": "name4",
      "Version": "1.0.0"
    },
    {
      "Group": "group5",
      "Name": "name5",
      "Version": "1.0.0"
    }
  ]
}

Demo

pmf
  • 24,478
  • 2
  • 22
  • 31
0

You want .packages |= . + [ { ... } ], which appends an element (well, an entire array, really), to the packages array, and not .packages[3] |= { ... }, which adds/merges some keys into the object at .packages[3].

hobbs
  • 223,387
  • 19
  • 210
  • 288
  • at this case a get group1,2,3,5,4. the new package object is at the end of the array, which breaks the numbering – Mateo Neo Dec 08 '21 at 10:32
0

You desire to insert a record into an array such that it remains sorted. The best and easiest solution is simply to append the record than sort the array. This has the advantage that knowing the insert position isn't needed.

.packages |= (
   . + [ { "Group": "group4", "Name": "name4", "Version": "1.0.0" } ] |
   sort_by( .Group )
)
ikegami
  • 367,544
  • 15
  • 269
  • 518