0

from time to time I have to parse over tons of logs that are in format. I want to write a function that I can include in my .bash_profile to simply go over last 4 hours in time range log starting from current date:

Logs format:

**IcyBoxy> **   less test.txt
Jan 14 05:29:50 Something1
Jan 14 06:31:01 Something2
Jan 14 07:32:01 Something3
Jan 14 07:33:01 Something4
Jan 14 08:34:01 Something5
Jan 14 08:35:01 Something6
Jan 14 08:30:01 Something7
Jan 14 08:30:01 Something8
Jan 14 08:30:01 Something9

**IcyBoxy>** date
Thu Jan 14 08:45:26 GMT 2016

**IcyBoxy>** filtering() { current=$(date +"%b %d %H");
> past=$(date +"%b %d %H" --date='-240 min');
> sed -n "/${current}/,/${past}/p" test.txt | grep "$@";  }

**IcyBoxy>** echo $past
Jan 14 04:39:31

**IcyBoxy>** echo $current
Jan 14 08:39:31

**IcyBoxy>** filtering Something
Jan 14 08:34:01 Something5
Jan 14 08:35:01 Something6
Jan 14 08:30:01 Something7
Jan 14 08:30:01 Something8
Jan 14 08:30:01 Something9

Why it is displaying only matching output from current hour, instead of taking all 4h range?

I can do it in different way, but it is not nice and requires more input from our side:

**IcyBoxy>** context () { sed -n -e "/$1/,/$2/ p" $3 | grep "$4" ;}
**IcyBoxy>** context 'Jan 14 05:29:50' 'Jan 14 08:30:02' test.txt Something
Jan 14 05:29:50 Something1
Jan 14 06:31:01 Something2
Jan 14 07:32:01 Something3
Jan 14 07:33:01 Something4
Jan 14 08:34:01 Something5
Jan 14 08:35:01 Something6
Jan 14 08:30:01 Something7

It catches all what I want.

Do you have idea how to make the 1st function work?

tripleee
  • 175,061
  • 34
  • 275
  • 318
creed
  • 172
  • 2
  • 13
  • I would not use `sed` for this, because there is no easy way to articulate a single regular expression to cover an arbitrary time range. For easy ranges (not crossing midnight, not crossing month or year boundaries) it's not infeasible, but there are easy alternatives which do not have to work around these issues. – tripleee Jan 14 '16 at 09:13
  • I've tried also: awk '$0>=from&&$0<=to' from="$current" to="$past"; and awk -v var1="$current" -v var2="$past" '$0>=from&&$0<=to' from="var1" to="var2" ; hmm, but it do not want to trigger as well. – creed Jan 14 '16 at 09:29
  • solved by: test() { x=`date +"%b %d %T"`; y=`date +"%b %d %T" --date '-240 min'`; grep "$@" test.log | awk -v from="$y" -v to="$x" '$0>=from&&$0<=to'; } Thx for redirecting to other thinking stream. :) – creed Jan 14 '16 at 10:25
  • Awk can handle time stamps quite reasonably by itself, and the approach you are taking basically repeats the problem I noted for the `sed` approach. The robust solution is to get the dates into machine-readable form and then just compare integers. And of course, piping `grep` to `awk` is [useless](http://www.iki.fi/era/unix/award.html#grep). – tripleee Jan 14 '16 at 10:40

0 Answers0