1

For finding a date in a log file I've arrived at the following crude command:

grep Updated /var/log/socklog/xbps/current | tail -n 1 | grep -Eo ^20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]

That does what I need, which is to output the date of the last system upgrade I did on my Void machine: for example 2019-01-24. But it's a pretty cumbersome line and quite crude as well. I assume there must be a more elegant solution to extract the needed date from this file. Incidentally, the date is comprised by the first 10 characters of the line containing the text grep'd/tail'd for (the last, or most recent, occurrence in the file). Any suggestions for a more elegant solution?

This line, btw, is being used to produce a motd so that when I log into my system I'll see something like "last system upgrade 2019-01-24." So I created a script /etc/motd.sh with that line in it, which then gets called from /etc/profile. Am I going about making the information visible in the correct way? What might be some other alternatives for doing what I want?

The script /etc/motd.sh looks like:

#!/bin/bash
echo last system upgrade $(grep Updated /var/log/socklog/xbps/current | tail -n 1 | grep -Eo ^20[0-9][0-9]-[0-9][0-9]-[0-9][0-9])

PS Here's a sample line from the log file, as requested:

2019-01-15T18:05:51.31699 user.notice: Jan 15 12:05:51 xbps-install: Installed `brotli-1.0.7_1' successfully (rootdir: /).
2019-01-15T18:05:51.35465 user.notice: Jan 15 12:05:51 xbps-install: Updated `xwininfo-1.1.4_2' successfully (rootdir: /).
  • 2
    I think it'd help answerers to see sample lines from the input file – Jeff Schaller Jan 25 at 0:36
  • I agree with Jeff, but also, if it works, it works. Without seeing the input file, it doesn't seem so inelegant to me. – Sparhawk Jan 25 at 0:44
  • The sample line doesn't have 'Updated' in it, is there more to the line? – user1794469 Jan 25 at 1:15
0

I'd probably use awk. Split fields at the T in the datestamp, look for Updated, and print the last occurrence.

awk -FT '/Updated/ {date=$1} END {print date}' /var/log/socklog/xbps/current

You can interpolate that directly, or take the slightly more readable approach

#!/bin/bash
#
updated=$(awk -FT '/Updated/ {date=$1} END {print date}' /var/log/socklog/xbps/current)
[[ -n "$updated" ]] && printf "Last system upgrade %s\n" "$updated"
  • This definitely looks more elegant than the multiple greps + tail that I came up with. Think I'll go ahead and mark it as the best answer. – MJiller Jan 26 at 5:04
2

If the date is first 10 characters, then you can use cut instead of the second grep

tail -n 1 | cut -c1-10
  • Yeah, this works too. But it doesn't do any streamlining--it still requires 2 pipes. Replaces one of the greps with cut. – MJiller Jan 26 at 15:07
  • Using pipes and a few simple operations might be more elegant than using no pipes an one convoluted command. It all depends on your circumstance. To me readability trumps brevity – Ilia Gilmijarow Jan 27 at 23:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.