今日以前の履歴を探す

今日以前の履歴を探す

「最後の日付」が今日の日付よりも早いレコード様式のデータを見つける方法です。つまり、今日の日付が2014年9月4日の場合は、「最後の日付」が2014年4月9日より前のレコードを探します。

-

Email ID : [email protected] 
Last Date : 30-04-2014
--
Email ID : [email protected] 
Last Date : 18-03-2014
--
Email ID : [email protected] 
Last Date : 18-02-2013
--
Email ID : [email protected] 
Last Date : 18-05-2015
--
Email ID : [email protected] 
Last Date : 01-05-2012
--
Email ID : [email protected] 
Last Date : 09-04-2014

予想される出力は次のとおりです。

Email ID : [email protected] 
Last Date : 18-03-2014
--
Email ID : [email protected] 
Last Date : 18-02-2013
--
Email ID : [email protected] 
Last Date : 01-05-2012

答え1

1つの方法はPerlを使用することです。データが示すように、入力チャンクを読み取り、入力レコード区切り文字を「--」に設定します。日 - 月 - 年の日付を数値的かつ相対的な比較可能な形式に戻します。 YYYYMMDD。包括的な:

#!/usr/bin/env perl
use strict;
use warnings;

my @t = localtime();
my $today = sprintf( "%04d%02d%02d", $t[5] + 1900, $t[4] + 1, $t[3] );

local $/ = "--"; #...record separator...

while (<>) {
    if (m{Last Date : (\d\d)-(\d\d)-(\d\d\d\d)}) {
        my $then = sprintf( "%04d%02d%02d", $3, $2, $1 );
        print if ( $then < $today );
    }
}
1;

「myfilter」スクリプトが必要ないと仮定すると、入力データをプログラムに転送するか、単に次のようにすることができます。

$ myfilter inputdata

答え2

Perlソリューションほどエレガントではありませんが、Awkを使用して基本的に同じアルゴリズムで同じことを行うことができます。

BEGIN{
    FS      = " : |\n"
    RS      = "--\n?"; 
    Padding = " 00 00 00"; 
    Today   = mktime(strftime("%Y %m %d") Padding);
}
{
    Last_date = gensub(/([0-9]{2})-([0-9]{2})-([0-9]{4})/, "\\3 \\2 \\1", "g", $4); 
        if (mktime(Last_date Padding) < Today) {
        sub(/\n$/, "", $0); 
        print Sep $0;
        Sep = "--\n"
    } 
}

答え3

perl別の解決策は次のとおりです。

$ perl -MTime::Local -nle '
BEGIN {
    $/ = "--"
}

($dd,$mm,$yy) = (localtime)[3..5];
$today = timelocal(0,0,0,$dd,$mm,$yy);
$h{$1} = $_ if /Last Date : (.*)$/;

END {
    print $h{$_} for grep {
        ($d,$m,$y)=split "-",$_;
        timelocal(0,0,0,$d,$m-1,$y) < $today;
    } keys %h
}' file

ここでは、入力日付が有効な日付でない場合を処理するtimelocal()コアモジュールの機能を使用して日付をepochに変換しています。Time::Local

関連情報