With a Json field like the one below, if eventId is a continuous value,I would like to add the value of the message field.
However, even if eventId is continuous, if the message field starts with # Time, the message field is separated.
This is the original field of Json.
{"events": [ {"message": "# Time: 1","eventId": "38636469249093328935961608873790523617989208925384015872" }, {"message": ", 2, 3","eventId": "38636469249093328935961608873790523617989208925384015873" }, {"message": "# Time: 11","eventId": "38636469249093328935961608873790523617989208925384015875" }, {"message": "# Time: 12","eventId": "38636469249093328935961608873790523617989208925384015876" }, {"message": "# Time: A","eventId": "1" }, {"message": ", B, C","eventId": "2" }, {"message": "# Time: C","eventId": "3" }, {"message": "# Time: D","eventId": "5" } ]}
Here's what I want it to look like:
[ {"message": "# Time: 1, 2, 3" }, {"message": "# Time: 11" }, {"message": "# Time: 12" }, {"message": "# Time: A , B, C" }, {"message": "# Time: C" }, {"message": "# Time: D" }]
I've asked a question about this before and received an answer from a great person. (Thank you pmf.)
After this, I tried my best to refine it a little more, but it didn't work, so I asked once more.
First, When Ifirst run this JQ, I get the following results.
jq -r '.events | reduce .[1:][] as $i (.[:1]; if ((.[-1].eventId | tonumber + 1 | tostring) != $i.eventId) or ($i.message | startswith("# Time:")) then . += [$i] else .[-1].message += " " + $i.message end) | del(.[].eventId)'
[ {"message": "# Time: 1" }, {"message": ", 2, 3" }, {"message": "# Time: 11" }, {"message": "# Time: 12" }, {"message": "# Time: A , B, C" }, {"message": "# Time: C" }, {"message": "# Time: D" }]
I saw it as a floating point issue and wanted to compare this number with the string itself, so I created a function as follows, but it did not work.
jq '# Function to add one to a large number represented as a stringdef add_one(num): (num | split("") | reverse | map(tonumber)) as $digits | reduce range(0; length) as $i ([]; . + if $i == 0 or .[-1] == 10 then [($digits[$i] + 1) % 10] else [$digits[$i]] end ) | reverse | map(tostring) | join("");# Process events and check continuity.events | map(.eventId |= tostring) # Ensure all eventIds are strings| reduce .[1:][] as $i (.[:1]; if (add_one(.[-1].eventId) != $i.eventId) or ($i.message | startswith("# Time:")) then . += [$i] else .[-1].message += " " + $i.message end)| del(.[].eventId)'
[ {"message": "# Time: 1" }, {"message": ", 2, 3" }, {"message": "# Time: 11" }, {"message": "# Time: 12" }, {"message": "# Time: A" }, {"message": ", B, C" }, {"message": "# Time: C" }, {"message": "# Time: D" }]
As I searched further, I found a command called gojq, but I would like to test it first to see if it is possible with jq.
I am using jq version 1.7.1.