将记录的日期时间转换为 UNIX 纪元时间戳的 Perl 脚本
Posted
技术标签:
【中文标题】将记录的日期时间转换为 UNIX 纪元时间戳的 Perl 脚本【英文标题】:Perl script to convert logged datetimes to UNIX epoch timestamps 【发布时间】:2013-03-25 17:07:30 【问题描述】:我有一个日志文件 (datetimes.log
),由数十万个时间戳组成:
YYYY-MM-DD HH:mm:ss
例如:
2013-03-28 06:43:51
2013-03-28 06:43:55
2013-03-28 06:44:03
...etc.
我想编写一个简单的 Perl 脚本来输出一个新的 unix_timestamps.log
文件,该文件包含相同的条目,但不是日期时间,而是具有相应的 UNIX 纪元时间戳。对于上面的示例,unix_timestamps.log
文件中将包含以下信息:
1364453031
1364453035
1364453043
...etc.
我唯一能想到的就是perl convert_2_timestamps.pl
:
#!/usr/bin/perl
use warnings;
use strict;
grep m/_(\d4)(\d\d)(\d\d)/ | POSIX::mktime(?, ?, ?, ?, ?, ?) > unix_timestamps.log
但不确定如何将参数传输到mktime
,并且不确定这是否是正确的方法。提前致谢。
【问题讨论】:
您真的希望将其与您之前的问题结合起来吗?由于您并不真正知道自己在做什么,也许您应该告诉我们您最终想要实现的目标是什么。这让事情变得容易多了。 ;-) 使用什么时区?本地? 【参考方案1】: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
【讨论】:
一些解释会很好。 我已经切换到使用 Time::Piece 来完成类似这样的简单解析任务。您不太可能让人们抱怨他们无法从 CPAN 安装模块 :-) @Dave 那是我的方式,你知道,TIMTOWTDI。但是有机会在不同的场景中安装 CPAN 模块。 哦,当然有!但是我发现,通过使用可用的核心模块,您可以专注于解决问题,而不是完全讨论非管理员如何安装 CPAN 模块。这只是我的实用主义:-) 我同意,避免潜在问题很聪明【参考方案2】:这是Time::Piece 模块的完美使用,该模块已成为 Perl 发行版的标准部分超过五年。
#!/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
【讨论】:
【参考方案3】:您可以像这样分解 YYYY-MM-DD HH:mm:ss 格式:
my ( $y, $m, @t ) = split /[-: ]+/, $time_str;
my $time = mktime( reverse @t, $m - 1, $y - 1900 );
但你也可以像这样把它放在一个替换中:
s(\d4)-(0?[1-9]\d?)-(0?[1-9]\d?) (0?\d1,2):(0?\d1,2):(0?\d1,2)
mktime( $6, $5, $4, $3, $2 - 1, $1 - 1900 )
e;
【讨论】:
【参考方案4】:试试Date::Parse
CPAN 模块。 (http://metacpan.org/pod/Date::Parse)
有了它,你的convert_2_timestamps.pl
就可以了:
#!/usr/bin/perl
use warnings;
use strict;
use Date::Parse;
while (<>)
chomp;
printf("%s\n", str2time("$_ GMT"));
请注意,我必须将 GMT 附加到您的示例输入中才能获得预期的输出。
运行方式:
perl convert_2_timestamps.pl < datetimes.log > unix_timestamps.log
【讨论】:
以上是关于将记录的日期时间转换为 UNIX 纪元时间戳的 Perl 脚本的主要内容,如果未能解决你的问题,请参考以下文章
如何将自纪元以来的 Unix 时间/时间转换为标准日期和时间?