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.