【问题标题】:Perl: How to perform date calculations from a parsed filePerl:如何从解析的文件执行日期计算
【发布时间】:2012-01-09 19:52:43
【问题描述】:

我有一个包含多列的 csv 文件。例子,

"00000089-6d83-486d-9ddf-30bbbf722583","2011-09-17 16:25:09","INTNAME","1001","https://mobile.mint.com:443"
"000004c9-92c6-4764-b320-b1403276321e","2011-11-09 13:52:30","INTNAME","2000","http://m.intel.com/content/intel-us/en/shop/shop-landing.html?t=laptop&p=13"

这些是我需要解析的大文件中的示例行。我只需要从这个文件中选择那些第四列在某个列表中的行(比如 1000、2000 ......)和特定日期之间的第二列(比如 2011-11-01 00:00:00 到2011-11-15 00:00:00)。

那么,我如何进行这些日期选择并仅以制表符分隔的形式输出这些行。

在示例中,仅选择第二行并以制表符分隔的形式保存在另一个文件中。

【问题讨论】:

    标签: perl parsing datetime csv


    【解决方案1】:

    你可能想看看Time::Piece,像这样使用它(例如):

    # use strftime() formats.
    my $time = Time::Piece->strptime($date, "%Y%m%d %H:%M");
    

    (为您的数据应用相关的 strftime 格式)

    【讨论】:

      【解决方案2】:

      首先,它看起来像 CSV,因此您应该使用 Text::CSV_XS(或 Text::CSV)来解析它。在 Perl 中用于处理日期/时间的“标准”模块是 DateTime,它与 DateTime::Format::ISO8601 或类似的模块一起使用,但 Date::Parse 也是一种可能性。

      【讨论】:

        【解决方案3】:

        使用Parse::CSV,这是一种完成工作的方法:

        #!/usr/local/bin/perl 
        use Modern::Perl;
        use Parse::CSV;
        
        my $parser = Parse::CSV->new(
            file => 'text.csv',
        );
        while ( my $value = $parser->fetch ) {
            if ($value->[3] > 1000 && $value->[3] <= 2000
              && $value->[1] gt '2011-11-01 00:00:00' 
              && $value->[1] lt '2011-11-15 00:00:00' ) {
                say "$value->[0] --> OK";
            }else {
                say "$value->[0] --> KO";
            }
        }
        

        输出:

        00000089-6d83-486d-9ddf-30bbbf722583 --> KO
        000004c9-92c6-4764-b320-b1403276321e --> OK
        

        您还可以使用过滤功能:

        my $parser = Parse::CSV->new(
            file => 'text.csv',
            filter => sub{
                    if ($_->[3] > 1000 && $_->[3] <= 2000
                     && $_->[1] gt '2011-11-01 00:00:00' 
                     && $_->[1] lt '2011-11-15 00:00:00' ) {
                       return $_;
                    }else {
                        return undef;
                    }
                }
        );
        
        while ( my $value = $parser->fetch ) {
            # do what you want with the filtered rows
        }
        

        【讨论】:

          【解决方案4】:
          #!/usr/bin/env perl
          use strict;
          use warnings;
          
          use 5.010;
          use utf8;
          use Carp;
          use Date::Parse;
          use English qw(-no_match_vars);
          
          our $VERSION = '0.01';
          
          my @list = qw(1000 2000 3000);
          
          #say "@list";
          # if ( '1000' ~~ @list ) {
          # say 'done';
          # }
          
          #s (say 2011-11-01 00:00:00 to 2011-11-15 00:00:00).
          
          my $start_date = str2time('2011-11-01 00:00:00');
          my $end_date   = str2time('2011-11-15 00:00:00');
          
          #my $input_time    = str2time($input_date);
          my $RGX_FOUR_FULL = qr{"([^"]+)","([^"]+)","([^"]+)","([^"]+)","([^"]+)"}smo;
          my $RGX_DATE_FULL = qr{.*"(\d{4}-\w{2}-\d{2} \d{2}:\d{2}:\d{2})".*}smo;
          my @input_data    = <DATA>;
          
          my @res =
          grep {
                extract_time($_) >= $start_date
            and extract_time($_) <= $end_date
            and ( extract_four($_) ~~ @list )
          } @input_data;
          
          print @res;
          
          #say 'Z';
          
          sub extract_time {
              my ($search_str) = @_;
              $search_str =~ s/$RGX_DATE_FULL/$1/sm;
              return str2time($search_str);
          }
          
          sub extract_four {
              my ($search_str) = @_;
              $search_str =~ s/$RGX_FOUR_FULL/$4/sm;
              chomp($search_str);
              #print $search_str;
              return $search_str;
          }
          
          __DATA__
          "00000089-6d83-486d-9ddf-30bbbf722583","2011-08-17 16:25:09","INTNAME","1001","https://mobile.mint.com:443"
          "00000089-6d83-486d-9ddf-30bbbf722583","2011-09-17 16:25:09","INTNAME","1001","https://mobile.mint.com:443"
          "000004c9-92c6-4764-b320-b1403276321e","2011-11-09 13:52:30","INTNAME","2000","http://m.intel.com/content/intel-us/en/shop/shop-landing.html?t=laptop&p=13"
          "000004c9-92c6-4764-b320-b1403276321e","2011-11-10 14:52:30","INTNAME","4000","http://m.intel.com/content/intel-us/en/shop/shop-landing.html?t=laptop&p=13"
          "000004c9-92c6-4764-b320-b1403276321e","2011-11-09 13:52:30","INTNAME","3000","http://m.intel.com/content/intel-us/en/shop/shop-landing.html?t=laptop&p=13"
          

          你得到

          "000004c9-92c6-4764-b320-b1403276321e","2011-11-09 13:52:30","INTNAME","2000","http://m.intel.com/content/intel-us/en/shop/shop-landing.html?t=laptop&p=13"
          "000004c9-92c6-4764-b320-b1403276321e","2011-11-09 13:52:30","INTNAME","3000","http://m.intel.com/content/intel-us/en/shop/shop-landing.html?t=laptop&p=13"
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-06-18
            • 2010-10-11
            • 1970-01-01
            • 2010-09-22
            • 2013-09-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多