0

I need to find a way for grep to return different line sized contents after a match. Some matches have 4 lines after them, other have 20. I need them all.

Every hour I am looking to return the previous hour's log entries, which have timestamps like:

time: 20200115132443

To do this, I imagine every hour a cronjob will run the previous hour's timestamp as a grep statement:

grep "time: 2020011507"

The problem I'm having is the log has different sizes for certain entries after a match, so just things like grep -C 5 won't really work all the time.

I'm wondering if I should either be returning all contents of a match up to the next matched grep statement (which would miss the last entry) or if there is some other way to run this. A sample log file snippet looks like:

time: 20200115132443
logging stuffs
time: 20200115134543
more logging 
stuffs 
like this
time: 20200115140201 # this should now not be returned

Maybe I am overcomplicating and can just run a grep statement of the current hour and just grab everything before that hour and after the hour previous.

1
  • 1
    This kind of thing is easier to do in awk ex. awk -v t="20200115134543" '/^time:/{if($2 == t) p=1; else p=0} p' file.log Jan 15 '20 at 14:10
1

Possible approach:

# variable S0 - date string for hour ago
S0="time: $(date -d '1 hour ago' +%Y%m%d%H)"
# Variable S1 - date string for current hour
S1="time: $(date +%Y%m%d%H)"
# taking lines from between two just defined strings
# including first and excluding second date string
# from file /var/log/log.log
sed -n "/^${S0}/,/^${S1}/ {/^${S1}/"'!p};' /var/log/log.log

Now trying to make this a compact one liner:

sed -n "/^time: $(date -d '1 hour ago' +%Y%m%d%H)/,/^time: $(date +%Y%m%d%H)/ {/^time: $(date +%Y%m%d%H)/"'!p}' /var/log/log.log

You can redirect output to a temp file and work with it.

Or you can simply just add to the end of one liner a pipe and grep:

|grep "mystring"

.

P.S. Depending on OS the command date format may differ.

  • Linux we used here: date -d '1 hour ago' +%Y%m%d%H

  • Linux we could use: date -d @$(($(date +%s)-3600)) +%Y%m%d%H

  • MacOS X: date -r $(($(date +%s)-3600)) +%Y%m%d%H

etc.

Updated: figured out that the sed part '$d' to delete the last found line does not work, so updated the sed line to work properly.

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.