Reputation: 56934
I have a log file (datetimes.log
) consisting of hundreds of thousands of timestamps of the form:
YYYY-MM-DD HH:mm:ss
For example:
2013-03-28 06:43:51
2013-03-28 06:43:55
2013-03-28 06:44:03
...etc.
I'd like to write a simple Perl script to output a new unix_timestamps.log
file that contains the same entries, but instead of the datetime, to have the corresponding UNIX epoch timestamp. For the example above, the unix_timestamps.log
file would have the following info in it:
1364453031
1364453035
1364453043
...etc.
The only thing I can think of is perl convert_2_timestamps.pl
:
#!/usr/bin/perl
use warnings;
use strict;
grep m/_(\d{4})(\d\d)(\d\d)/ | POSIX::mktime(?, ?, ?, ?, ?, ?) > unix_timestamps.log
But not sure how to transfer the parameters into mktime
, and not sure if this is even the right approach. Thanks in advance.
Upvotes: 1
Views: 4093
Reputation: 1833
Try the Date::Parse
CPAN module. (http://metacpan.org/pod/Date::Parse)
With it, your convert_2_timestamps.pl
can be just:
#!/usr/bin/perl
use warnings;
use strict;
use Date::Parse;
while (<>) {
chomp;
printf("%s\n", str2time("$_ GMT"));
}
Note that I had to append GMT to your example input to get your expected output.
Run as:
perl convert_2_timestamps.pl < datetimes.log > unix_timestamps.log
Upvotes: 0
Reputation: 69314
This is a perfect use for the Time::Piece module which has been a standard part of the Perl distribution for over five years.
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
use Time::Piece;
# Read the data a record at a time. Data ends up in $_.
# N.B. Using built-in DATA filehandle for this demo.
# In the real world you'd open a separate filehandle.
while (<DATA>) {
chomp;
# Create a Time::Piece object using strptime (that's "string
# parse time") and immediately call the epoch method on the
# new object to get the value you want.
say Time::Piece->strptime($_, '%Y-%m-%d %H:%M:%S')->epoch;
}
__DATA__
2013-03-28 06:43:51
2013-03-28 06:43:55
2013-03-28 06:44:03
Upvotes: 2
Reputation: 29854
You could break up the YYYY-MM-DD HH:mm:ss format like so:
my ( $y, $m, @t ) = split /[-: ]+/, $time_str;
my $time = mktime( reverse @t, $m - 1, $y - 1900 );
But you could also put it in a replace like so:
s{(\d{4})-(0?[1-9]\d?)-(0?[1-9]\d?) (0?\d{1,2}):(0?\d{1,2}):(0?\d{1,2})}{
mktime( $6, $5, $4, $3, $2 - 1, $1 - 1900 )
}e;
Upvotes: 1
Reputation: 13792
use strict;
use warnings;
use DateTime::Format::Strptime;
my $parser = DateTime::Format::Strptime->new(
pattern => '%Y-%m-%d %H:%M:%S',
on_error => 'croak',
);
while( <DATA> ) {
my $dt = $parser->parse_datetime($_);
print $dt->epoch, "\n";
}
__DATA__
2013-03-28 06:43:51
2013-03-28 06:43:55
2013-03-28 06:44:03
Upvotes: 4