codeObserver
codeObserver

Reputation: 6657

grep between date ranges in a log

I am trying to grep all the lines between 2 date ranges , where the dates are formatted like this : date_time.strftime("%Y%m%d%H%M") so say between [201211150821 - 201211150824]

I am trying to write a script which involves looking for lines between these dates:

cat <somepattern>*.log | **grep [201211150821 -  201211150824]** 

I am trying to find out if something exists in unix where I can look for a range in date.

I can convert dates in logs to (since epoch) and then use regular grep with [time1 - time2] , but that means reading each line , extracting the time value and then converting it etc .

May be something simple already exist , so that I can specify date/timestamp ranges the way I can provide a numeric range to grep ?

Thanks!

P.S: Also I can pass in the pattern something like 2012111511(27|28|29|[3-5][0-9]) , but thats specific to ranges I want and its tedious to try out for different dates each time and gets trickier doing it at runtime.

Upvotes: 8

Views: 9637

Answers (5)

Vadim Goryunov
Vadim Goryunov

Reputation: 781

I wrote a specific tool for similar searches - http://code.google.com/p/bsearch/

In your example, the usage will be:

$ bsearch -p '$[YYYYMMDDhhmm]' -t 201211150821 -t 201211150824 logfile.

Upvotes: 0

mdo
mdo

Reputation: 7111

Bash + coreutils' expr only:

export cmp=201211150823 ; cat file.txt|while read line; do range=$(expr match "$line" '.*\[\(.*\)\].*'); [ "x$range" = "x" ] && continue; start=${range:0:12}; end=${range:15:12}; [ $start -le $cmp -a $end -ge $cmp ] && echo "match: $line"; done

cmp is your comparison value,

Upvotes: 0

user1666959
user1666959

Reputation: 1855

You are looking for the somewhat obscure 'csplit' (context split) command:

csplit '%201211150821%' '/201211150824/' file

will split out all the lines between the first and second regexps from file. It is likely to be the fastest and shortest if your files are sorted on the dates (you said you were grepping logs).

Upvotes: 1

ruakh
ruakh

Reputation: 183602

A Perl solution:

perl -wne 'print if m/(?<!\d)(20\d{8})(?!\d)/
                      && $1 >= 201211150821 && $1 <= 201211150824'

(It finds the first ten-digit integer that starts with 20, and prints the line if that integer is within your range of interest. If it doesn't find any such integer, it skips the line. You can tweak the regex to be more restrictive about valid months and hours and so on.)

Upvotes: 2

schtever
schtever

Reputation: 3250

Use awk. Assuming the first token in the line is the timestamp:

awk '
BEGIN { first=ARGV[1]; last=ARGV[2]; }
$1 > first && $1 < last { print; }
' 201211150821 201211150824

Upvotes: 2

Related Questions