ygoe
ygoe

Reputation: 20442

How to compare a value with the previous object?

I'm using jq to format the log entries from journalctl -o json in a readable way. While that works nicely, I'm missing the journalctl indicator for a reboot. This information isn't directly included in the json format output. But it can be inferred by comparing the _BOOT_ID value of the current object with the one on the previous line. If they are different, the message belongs to another boot session and I need to insert that "-- Reboot --" line.

How can I compare that value in jq?

The following is a simple version of what I'm doing:

journalctl -o json --since today |jq -r '
  "\(._SOURCE_REALTIME_TIMESTAMP // .__REALTIME_TIMESTAMP |tonumber |. / 1000000 |strflocaltime("%m-%d %H:%M:%S")) \(.SYSLOG_IDENTIFIER // .UNIT): \(.MESSAGE)"
' |less

It shows a timestamp, unit name, and the message. What I'm looking for is something like the following (where $$previous$$ does not exist):

journalctl -o json --since today |jq -r '
  "\(if ._BOOT_ID != $$previous$$._BOOT_ID then "-- Reboot --\n" else "" end)\(._SOURCE_REALTIME_TIMESTAMP // .__REALTIME_TIMESTAMP |tonumber |. / 1000000 |strflocaltime("%m-%d %H:%M:%S")) \(.SYSLOG_IDENTIFIER // .UNIT): \(.MESSAGE)"
' |less

I'd also accept setting variables at the end of one line and accessing them at the beginning of the next line; but variables don't seem to exist, I could only set a property of the current object which won't help.

Upvotes: 0

Views: 228

Answers (1)

peak
peak

Reputation: 117057

A solution can be obtained using foreach along the following lines:

jq -nr '
  foreach inputs as $entry (null;
    $entry 
    + if (. != null) and (._BOOT_ID != $entry._BOOT_ID)
      then {emit: true} else null end;
   if .emit then "-- Reboot --" else empty end,
   .foo)
'   

You would replace .foo with the filter defining the projection of interest.

Upvotes: 1

Related Questions