【问题标题】:Perl script to convert logged datetimes to UNIX epoch timestamps将记录的日期时间转换为 UNIX 纪元时间戳的 Perl 脚本
【发布时间】: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/_(\d{4})(\d\d)(\d\d)/ | POSIX::mktime(?, ?, ?, ?, ?, ?) > unix_timestamps.log

但不确定如何将参数传输到mktime,并且不确定这是否是正确的方法。提前致谢。

【问题讨论】:

  • 您真的希望将其与您之前的问题结合起来吗?由于您并不真正知道自己在做什么,也许您应该告诉我们您最终想要实现的目标是什么。这让事情变得容易多了。 ;-)
  • 使用什么时区?本地?

标签: perl grep timestamp epoch


【解决方案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{(\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;
    

    【讨论】:

      【解决方案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
      

      【讨论】:

        猜你喜欢
        • 2018-08-03
        • 2013-01-08
        • 2021-02-19
        • 2015-12-22
        • 2014-01-25
        • 2016-09-15
        • 2018-12-27
        • 2020-10-19
        相关资源
        最近更新 更多