0

I have JSON

[
  {"id": "1"},
  {"id": "5"},
  {"id": "9"},
  {"id": "0"},
  {"id": "3"}
]

I want to insert an object to produce:

[
  {"id": "1"},
  {"id": "5"},
  {"id": "2"},
  {"id": "9"},
  {"id": "0"},
  {"id": "3"}
]

How do I do this jq? Either by index or relative to other objects.

EDIT: This is not a duplicate of Add new element to existing JSON array with jq , which is about appending/prepending elements to arrays. As stated, I want to insert an element.

peak
  • 105,803
  • 17
  • 152
  • 177
Paul Draper
  • 78,542
  • 46
  • 206
  • 285
  • 1
    do you mean insert at a specific index? or anywhere in the array should be fine? – Inian Mar 01 '21 at 19:48
  • Does this answer your question? [Add new element to existing JSON array with jq](https://stackoverflow.com/questions/42245288/add-new-element-to-existing-json-array-with-jq) – Inian Mar 01 '21 at 19:48
  • Also - [Add JSON Object at specific location](https://stackoverflow.com/q/59629569/5291015) – Inian Mar 01 '21 at 20:01
  • Please follow the [mcve] guidelines. It would also help if you gave an example of what you tried. – peak Mar 01 '21 at 20:14
  • @Inian, "either by index or relative to other objects" – Paul Draper Mar 01 '21 at 23:50
  • @peak what do you thing my example lacks? – Paul Draper Mar 01 '21 at 23:50
  • @PaulDraper - the first line of [mcve] says "if you provide code"; the "m" stands for "minimal". Also, where does the item to be inserted come from? "Relative" could mean many things in this context. E.g. the first .id greater than 5? Immediately prior to the first .id greater than 8? .... – peak Mar 02 '21 at 03:13
  • @peak, those relative solutions would be acceptable. Thank you for working to provide me an answer. – Paul Draper Mar 03 '21 at 02:52

2 Answers2

2

I'm not sure whether that's a good solution at all but there you go:

From:

[0, 1, 3]

To:

[0, 1, 2, 3]

With:

jq '[.[0:2][], 2, .[2:][]]' input.json
//   ^         ^  ^
//   A         B  C
  • A: 1st filter: all the items before the new item
  • B: 2nd filter: your new item
  • C: 3rd filter: all items after the new item
customcommander
  • 17,580
  • 5
  • 58
  • 84
0

Here are two defs for inserting an item into an array:

# Insert $x into the input array, such that after insertion,
# if $i is in range(0;length+1), then .[$i] == $x
def insert($i; $x): .[:$i] + [$x] + .[$i:];

# Emit the zero-based index of $needle in the stream, s, but if s is empty, emit null:
def index_of($needle; s):
 label $go
 | foreach s as $x (-1; .+1; select($x==$needle) | (., break $go)) // null;

# Insert $x after the first occurrence of $needle in the input array,
# but if $needle is not present, then append $x:
def insert_after($needle; $x):
 index_of($needle; .[]) as $ix
 | if $ix then insert($ix + 1; $x) else . + [$x] end;
peak
  • 105,803
  • 17
  • 152
  • 177