Reputation: 53
I'm scrolling through the jq Manual and reading through every command available, but am only about 10% complete in reading it. (It's quite long, which is a good thing except that I have an art project presentation due in six days and I have to finish with this JSON analysis first so I can start measuring a cutting 350 meters of tape.)
I have a JSON file with exactly one object. That one object contains an array of 3555 JSON objects, which can be accessed via its index numbered from 0 to 3554. This shows the structure of one of those JSON objects (I've modified the phone numbers and the body/content of the instant message since this comes from a real conversation):
$ cat selected-convo.json | jq '.[3554]'
{
"timestamp": 1589547750278,
"attachments": [],
"source": "+491604444444",
"sourceUuid": "a258be99-b00a-456d-bba6-258d72878b64",
"sourceDevice": 1,
"sent_at": 1589536960941,
"sent_to": [
"+31707777777"
],
"received_at": 1589547750278,
"conversationId": "823c0416-9406-4922-8ee9-f3cf36c4784c",
"type": "outgoing",
"sent": true,
"unidentifiedDeliveries": [
"+31707777777"
],
"expirationStartTimestamp": 1589536960941,
"schemaVersion": 10,
"id": "42e9ed93-ad1e-44fc-912a-dd310c16b52e",
"body": "X xxxx X xxxx X xxx xxxxxxxxx xx xxx.",
"contact": [],
"decrypted_at": 1589547750368,
"errors": [],
"flags": 0,
"hasAttachments": 0,
"isViewOnce": false,
"preview": [],
"requiredProtocolVersion": 0,
"supportedVersionAtReceive": 4,
"quote": null,
"sticker": null,
"recipients": [
"+31707777777"
]
}
I am only interested in measuring the time it took one person to respond to the other person. So, the key-value pairs I want are the sent at timestamp and whether the message is incoming or outgoing.
$ cat selected-convo.json | jq '.[] | .sent_at, .type'
give me the following output (first ten in the array of 3555):
1577640636917
"outgoing"
1577674806478
"incoming"
1577674810527
"incoming"
1578513043504
"outgoing"
1578520666264
"outgoing"
1580600735958
"outgoing"
1580600816040
"outgoing"
1580601327790
"incoming"
1580602829082
"outgoing"
1580602833184
"outgoing"
BUT, I only want to see the first outgoing message followed by the first incoming message followed by the next outgoing message followed by the next incoming message, etc. (If I sent three messages in a row, I want do delete/ignore the second and third message and only look at the first one. If I received eight messages in a row before I responded, I want to only see the first of those messages and delete/skip/forward past the following seven. So from the list above, I want:
1577640636917
"outgoing"
1577674806478
"incoming"
1578513043504
"outgoing"
1580601327790
"incoming"
1580602829082
"outgoing"
Any ideas?
Upvotes: 1
Views: 595
Reputation: 50775
I'd use foreach
for that as the task basically requires a state machine that extracts some values from the current input whenever the state changes.
foreach .[] as {$type, $sent_at} (
{};
{prev: .curr, curr: $type};
if .curr != .prev
then $type, $sent_at
else empty end
)
Upvotes: 2