CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Regular Expressions:
Patern Matching within a Range of Ranges?

 



brian.hayes
User

Jun 13, 2001, 10:59 AM

Post #1 of 3 (4517 views)
Patern Matching within a Range of Ranges? Can't Post

Just how can you extract data from a file based on a start time and end time?

Example:
My Date is 25-May-01
My start time is 03:00pm
My end time is 05:21pm
My Name is "BatchSMF" Not "BatchSMF01"

What I need is everything from the two time ranges and every thing in between.

Example Data:

25-May-01 03:00pm 1 batchSMF Good
25-May-01 03:00pm 1 batchSMF Good
25-May-01 03:01pm 1 batchSMF Bad
25-May-01 03:02pm 1 batchSMF01 Good
25-May-01 03:02pm 1 batchSMF Good
25-May-01 03:20pm 1 batchSMF Bad
25-May-01 05:29pm 1 batchSMF Good

Below is the code I have been working on, but I am getting lost fast!

Thanks,

Brian Hayes


Code
die("USAGE: Portia Log Check: <filename> <date(yyyy/mm/dd)> <hh:mm:am-pm> <hh:mm:am-pm> <batchoperator>") if(@ARGV < 5); 
die("Missing Portia Log file to Parse.") unless($ARGV[0] ne "");
die("Be sure that date is in yy/mm/dd format") unless($ARGV[1] =~ /\b\d\d\D\d\d\D\d\d\b/o);
die("Be sure that time is in HH:mm:am or pm format") unless($ARGV[2] =~ /\b\d\d\D\d\d\D\D\D\b/o);
die("Be sure that time is in HH:mm:am or pm format") unless($ARGV[3] =~ /\b\d\d\D\d\d\D\D\D\b/o);
die("Missing Batch Operator Name") unless($ARGV[4] ne "");

$filetoparse = $ARGV[0];

($year, $month, $day) = split(/\D/, $ARGV[1]);
@Months = ( "Jan|01",
"Feb|02",
"Mar|03",
"Apr|04",
"May|05",
"Jun|06",
"Jul|07",
"Aug|08",
"Sep|09",
"Oct|10",
"Nov|11",
"Dec|12" );

foreach $_(@Months){
print $_ , "\n";
my ($Des,$num) = split(/\|/,$_);
if($num == $month){ $month = $Des; }
}
$dateToMatch = $day."-".$month."-".$year;

my ($shour,$smin,$sampm) = split(/\:/, $ARGV[2]);
my ($thour,$tmin,$tampm) = split(/\:/, $ARGV[3]);

$Operator = $ARGV[4];

print $filetoparse, "\n";
print $dateToMatch, "\n";
print $startTime, "\n";
print $stopTime, "\n";
print $Operator, "\n";


open(LOGFILE, $ARGV[0]) or die("Could not open $ARGV[0]");
while(<LOGFILE>){
next if !/.{0}$dateToMatch.*$/o; #Read lines that Match the Date Stamp Provided.
#Lets work through our time range, not clean, but works.
for $myhour($shour .. $thour){
next if !/.{10}$myhour.*$/o; #Read lines the Match our Hour.
for $mymin($smin .. $tmin){
$mystoptime = $mymin.$ampm;
next if !/.{13}$mystoptime.*$/o; #Read lines that Match our Minutes.
##----- The AM or PM function is not working.....
next if !/.{24}$Operator.*$/o; # Read lines that Match our Operator
## This is also doing a part match, not sure if this is O.K.
## E.G The Operator in the file is batchSMF, Do a search for batchs will return true. !!! Not Good..
## Needs to be exact.
print $_ if(m/Bad/);
}
}
#close(LOGFILE) and die("File contains invalid date") unless(/.{0}$dateToMatch.*$/o);
}
close(LOGFILE);




mhx
Enthusiast

Jun 13, 2001, 10:44 PM

Post #2 of 3 (4511 views)
Re: Patern Matching within a Range of Ranges? [In reply to] Can't Post

Hi Brian,

I'm not absolutely sure what you want to do, but here's my solution. The code snippet reads a logfile from STDIN (you can use any file, but for testing I always use STDIN because I don't have to open() and close() it) and prints all lines that have a date and time in the range defined by $start and $end.
It uses the Date::Parse package to convert date/time strings to linear time values. Format checking is done with a small regex, conversion is done using Date::Parse and the range matching is done with the grep function.

Code
#!/bin/perl -w 
use Date::Parse;
use strict;

# define a regex that matches a date and time

my $dtregex = '\d{2}-[ADFJMNOS][a-z]{2}-\d{2}\s+\d{2}:\d{2}[ap]m';

# define start and end time

my $start = str2time( '25-May-01 03:00pm' );
my $end = str2time( '25-May-01 05:21pm' );

# grep all lines that have a time that fits
# in the range defined by $start and $end

my @lines = grep {

# put date/time string into $1
/($dtregex)/;

# convert to a time value
my $cur = str2time( $1 );

# check the range
$cur >= $start && $cur <= $end

} <>; # read the log file from STDIN

# just print the grepped lines
print @lines;

I hope you can draw any useful information from this.

-- Marcus



brian.hayes
User

Jun 14, 2001, 12:42 PM

Post #3 of 3 (4506 views)
Re: Patern Matching within a Range of Ranges? [In reply to] Can't Post

Perfect. Thanks for the information.

However I did make a change to your RegEx to accomidate for the date differences of a sigle digit day vs. a double digit day.

Example:
2-May-01
and
10-May-01

I Changed the first "\d{2}" to "\d{1,2}"

my $dtregex = '\d{1,2}-[ADFJMNOS][a-z]{2}-\d{2}\s+\d{2}:\d{2}[ap]m';


 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives