• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 232
  • Last Modified:

Split file into two files using Perl

I am a Perl neophyte.  I would like to take logs and split them into two files based upon a timestamp in the logs.  The timestamp is in the following format;

11/27/06 3:45:24 PM.

   Basically I want a business hours and a non-business hours file for each day.  I want everything from say 7 AM to 9 PM to be business houts and everything outside of this to be non business hours.  How do I accomplish this?

Perl neophyte
0
awakenings
Asked:
awakenings
  • 7
  • 3
  • 2
  • +1
7 Solutions
 
awakeningsAuthor Commented:
I will be working in SUSE.
0
 
ozoCommented:
open B,">business" or die $!;
open N,">non-business" or die $!;
while( <> ){
    if( /\b([7-9]|1[01]):\d\d:\d\d\s*AM\b/i || /\b(12|[1-9]):\d\d:\d\d\s*PM\b/i ){
       print B;
   }else{
      print N;
   }
}
0
 
mjcoyneCommented:
If you need to further define business hours from non-business hours (for example, all hours on a weekend or a holiday might be considered non-business hours, regardless of the time of day), see Date::Manip (http://www.cise.ufl.edu/~sbeck/DateManip.html).
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
awakeningsAuthor Commented:
Thanks folks!  Things became very busy yesterday and I didn't have time to get around to this.  I'll be testing this morning to make sure I have everything.
0
 
awakeningsAuthor Commented:
Ozo,

    Please forgive my ignorence on this.  I am no programmer of any sort and I am trying to understand basics.  One of the things I forgot to mention was that I am taking logs from actual files.  I am not sure I see how to do that.  The files have dates so I am looking at the following functions added on to what you suggested.

#!/usr/bin/perl

my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);

$year += 1900;
$mon += 1;
$mday = sprintf("%0.2d", $mday);
$mon = sprintf("%0.2d", $mon);

$date_string = "$mon-$mday-$year";

print "$date_string\n";

open LogFile$date_string\n.txt  (<---  Key part I am not sure of)

open B,">business" or die $!;
open N,">non-business" or die $!;
while( <> ){
    if( /\b([7-9]|1[01]):\d\d:\d\d\s*AM\b/i || /\b(12|[1-9]):\d\d:\d\d\s*PM\b/i ){
       print B;
   }else{
      print N;
   }
}

   Now how do I output this information to another txt file?  I want to run this in cron daily so I don't have to do anything with it.
0
 
awakeningsAuthor Commented:
Oh... As for  the comment about vacations, Saturdays and Sundays are considered non-business hours as well.

Thanks,

Perl Neophyte
0
 
ozoCommented:
open LogFile, "<$date_string.txt" or die "can't open $date_string.txt $!"; #  (<---  Key part I am not sure of)

open B,">business" or die $!;
open N,">non-business" or die $!;
while( <LogFile> ){
    if( /\b([7-9]|1[01]):\d\d:\d\d\s*AM\b/i || /\b(12|[1-9]):\d\d:\d\d\s*PM\b/i ){
       print B;
   }else{
      print N;
   }
}
#Although this ignores weekends and holidays
0
 
Adam314Commented:
This version looks at day of the week.  Saturday/Sunday go to non-business file...



use Time::Local;

open LogFile, "<$date_string.txt" or die "can't open $date_string.txt $!"; #  (<---  Key part I am not sure of)
open B,">business" or die $!;
open N,">non-business" or die $!;
while(<LogFile>){
      if(/(\d{2})\/(\d{2})\/(\d{2}) (\d{1,2}):(\d{2}):(\d{2}) (A|P)M/){
            my $hr=$4;
            my $hr+=12 if $7 eq 'P';
            my $datetime = timelocal($6,$5,$hr,$2,$1-1,$3+2000);
            my @localdate=localtime($datetime);
            my $secs=$localdate[0]+60*$localdate[1]+60*60*$localdate[2];
            if(   ($localdate[6] == 0)    #sunday
               || ($localdate[6] == 6)    #saturday
               || ($secs < 7*60*60)       #before 7 am
               || ($secs > 21*60*60) ){   #after 9 pm
                  print N;
            }
            else {
                  print B;
            }
      }
}
close N;
close B;
close LogFile;
0
 
ozoCommented:
And if you want to define holidays like Good Friday or Thanksgiving or Yom Yippur or Qi Xi you can use Date::Manip with a *Holiday section in the config file to define them
0
 
mjcoyneCommented:
"And if you want to define holidays like Good Friday or Thanksgiving or Yom Yippur or Qi Xi you can use Date::Manip with a *Holiday section in the config file to define them"

Didn't I already say that?  :)
0
 
awakeningsAuthor Commented:
Thanks everyone. Work has kept me busy so I've been slow.  I'm getting a permission denied error so I am troubleshooting through that.

Perl Neophyte
0
 
awakeningsAuthor Commented:
Okay... With some fenegalling I managed to get the file to run.  My file appears as follows.

#!/usr/bin/perl
use Time::Local;

my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);

$year += 1900;
$mon += 1;
$mday = sprintf("%0.2d", $mday);
$mon = sprintf("%0.2d", $mon);

$date_string = "$mon-$mday-$year";

open LogFile, "</home/mwebster/domain/fetch/sys$date_string.txt" or die "can't open $date_string.txt $!";
open sysB,">business" or die $!;
open sysN,">non-business" or die $!;
while(<LogFile>){
     if(/(\d{2})\/(\d{2})\/(\d{2}) (\d{1,2}):(\d{2}):(\d{2}) (A|P)M/){
          my $hr=$4;
          my $hr+=12 if $7 eq 'P';
          my $datetime = timelocal($6,$5,$hr,$2,$1-1,$3+2000);
          my @localdate=localtime($datetime);
          my $secs=$localdate[0]+60*$localdate[1]+60*60*$localdate[2];
          if(   ($localdate[6] == 0)    #sunday
             || ($localdate[6] == 6)    #saturday
             || ($secs < 7*60*60)       #before 7 am
             || ($secs > 21*60*60) ){   #after 9 pm
               print sysN;
          }
          else {
               print sysB;
          }
     }
}

     I can't find where sysN or sysB output the files to.  I need this to end in separate files.

Thanks,
0
 
Adam314Commented:
These lines open the files sysN and sysB (named 'business' and 'non-business' in the current directory)
    open sysB,">business" or die $!;
    open sysN,">non-business" or die $!;
if either failed, you will see an error message, and the program won't continue.

then, this line gets the date and time from the file
    if(/(\d{2})\/(\d{2})\/(\d{2}) (\d{1,2}):(\d{2}):(\d{2}) (A|P)M/){

then, these lines convert that date/time in the format of the file to time value (seconds since epoch)
    my $hr=$4;
    my $hr+=12 if $7 eq 'P';
    my $datetime = timelocal($6,$5,$hr,$2,$1-1,$3+2000);
    my @localdate=localtime($datetime);

then, these lines check if it is a business or non-business hours
    my $secs=$localdate[0]+60*$localdate[1]+60*60*$localdate[2];
    if(   ($localdate[6] == 0)    #sunday
       || ($localdate[6] == 6)    #saturday
       || ($secs < 7*60*60)       #before 7 am
       || ($secs > 21*60*60) ){   #after 9 pm

This line prints to the sysN file
    print sysN;

This line prints to the sysB file
    print sysB;
0
 
awakeningsAuthor Commented:
Ah...  My bad...  I didn't realize how perl was spitting them out.  Thanks!  The rest of the menutia, I can handle.  I'll assign points now.

Awakenings
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 7
  • 3
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now