Home > Mobile >  Cumulative variable for a real-time input and output stream of objects?
Cumulative variable for a real-time input and output stream of objects?

Time:07-29

I am dealing with a real-time, never-ending stream of objects.

Is there way to have a variable keeping its value from object to object without waiting until the end of the stream, outputting it immediately after JQ processed the next object from input?

For example, to have average temperature for all temperature measurements so far?

Input:

{"temp":10}
{"temp":20}
{"temp":15}
{"temp":11}

with code like

jq -n --unbuffered '
inputs
| magic(.temp, $count, $avg) as $avg
| {temp, $avg}'

Output:

{"temp":10, "avg":10}
{"temp":20, "avg":15}
{"temp":15, "avg":15}
{"temp":11, "avg":14}

CodePudding user response:

Yes! Or at least if your OS allows that sort of thing (*).

The trick is to use foreach, like so:

< stream.json jq -nc --unbuffered '
foreach inputs as $in ({};
   if .n == null then {n: 1, total: $in.temp}
   else .n  = 1 | .total  = $in.temp
   end;
   $in   {avg: (.total / .n )})
'

or more concisely:

< stream.json jq -nc --unbuffered '
foreach inputs as $in ({};
   .n  = 1 | .total  = $in.temp;
   $in   {avg: (.total / .n )})
'

(*) I've tested this using a bash shell.

  • Related