Unix 改进“计算天数”命令的步骤

Unix 改进“计算天数”命令的步骤,unix,awk,Unix,Awk,要生成报告,计算物料在仓库中的天数。 天数是物料输入日期和输入日期之间的差值。($3字段) 根据(2014年10月1日)手动进给日期 Input.csv Des11,Material,DateIN,Des22,Des33,MRP,Des44,Des55,Des66,Location,Des77,Des88 aa,xxx,19-AUG-14.08:08:01,cc,dd,x20,ee,ff,gg,XX128,hh,jj aa,xxx,19-AUG-14.08:08:01,cc,dd,x20,ee,

要生成报告,计算物料在仓库中的天数。 天数是物料输入日期和输入日期之间的差值。
($3字段)
根据
(2014年10月1日)
手动进给日期

Input.csv

Des11,Material,DateIN,Des22,Des33,MRP,Des44,Des55,Des66,Location,Des77,Des88
aa,xxx,19-AUG-14.08:08:01,cc,dd,x20,ee,ff,gg,XX128,hh,jj
aa,xxx,19-AUG-14.08:08:01,cc,dd,x20,ee,ff,gg,XX128,hh,jj
aa,yyy,13-JUN-14.09:06:08,cc,dd,x20,ee,ff,gg,XX128,hh,jj
aa,yyy,13-JUN-14.09:06:08,cc,dd,x20,ee,ff,gg,XX128,hh,jj
aa,yyy,05-FEB-14.09:02:09,cc,dd,x20,ee,ff,gg,YY250,hh,jj
aa,yyy,05-FEB-14.09:02:09,cc,dd,y35,ee,ff,gg,YY250,hh,jj
aa,zzz,05-FEB-14.09:02:09,cc,dd,y35,ee,ff,gg,YY250,hh,jj
aa,zzz,11-JUN-13.05:06:17,cc,dd,y35,ee,ff,gg,YY250,hh,jj
aa,zzz,11-JUN-13.05:06:17,cc,dd,y35,ee,ff,gg,YY250,hh,jj
aa,zzz,11-JUN-13.05:06:17,cc,dd,y35,ee,ff,gg,YY250,hh,jj
目前,我正在使用下面的命令在$13字段中显示老化天数(
感谢GBOFI

在Cygwin(windows)中使用上述命令时,1行Lac(100000)样本输入需要
50分钟。
由于我的实际输入文件包含2500万行
,脚本似乎需要几天时间, 期待您的建议,以改善命令和建议

预期产出:

Des11,Material,DateIN,Des22,Des33,MRP,Des44,Des55,Des66,Location,Des77,Des88,Ageing-NoOfDays
aa,xxx,19-AUG-14.08:08:01,cc,dd,x20,ee,ff,gg,XX128,hh,jj,42.6611
aa,xxx,19-AUG-14.08:08:01,cc,dd,x20,ee,ff,gg,XX128,hh,jj,42.6611
aa,yyy,13-JUN-14.09:06:08,cc,dd,x20,ee,ff,gg,XX128,hh,jj,109.621
aa,yyy,13-JUN-14.09:06:08,cc,dd,x20,ee,ff,gg,XX128,hh,jj,109.621
aa,yyy,05-FEB-14.09:02:09,cc,dd,x20,ee,ff,gg,YY250,hh,jj,237.624
aa,yyy,05-FEB-14.09:02:09,cc,dd,y35,ee,ff,gg,YY250,hh,jj,237.624
aa,zzz,05-FEB-14.09:02:09,cc,dd,y35,ee,ff,gg,YY250,hh,jj,237.624
aa,zzz,11-JUN-13.05:06:17,cc,dd,y35,ee,ff,gg,YY250,hh,jj,476.787
aa,zzz,11-JUN-13.05:06:17,cc,dd,y35,ee,ff,gg,YY250,hh,jj,476.787
aa,zzz,11-JUN-13.05:06:17,cc,dd,y35,ee,ff,gg,YY250,hh,jj,476.787
我没有权限更改输入格式,也没有perl和python访问权限

更新#3:

BEGIN{ FS=OFS=","} 
{ 
t1=$3
t2="01-OCT-14.00:00:00"
print $0,(cvttime(t2) - cvttime(t1))/24/3600
}

function cvttime(t,     a) {
        split(t,a,"[-.:]")
        match("JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC",a[2])
        a[2] = sprintf("%02d",(RSTART+2)/3)
        return( mktime("20"a[3]" "a[2]" "a[1]" "a[4]" "a[5]" "a[6]) )
}

因为您使用的是cygwin,所以您使用的是GNU awk,它有自己的内置时间函数,因此您不需要尝试使用shell
date
命令。只需调整我的旧命令,以适应您的输入和输出格式:

function cvttime(t,     a) {
        split(t,a,"[/:]")
        match("JanFebMarAprMayJunJulAugSepOctNovDec",a[2])
        a[2] = sprintf("%02d",(RSTART+2)/3)
        return( mktime(a[3]" "a[2]" "a[1]" "a[4]" "a[5]" "a[6]) )
}
BEGIN{
t1="01/Dec/2005:00:04:42"
t2="01/Dec/2005:17:14:12"
print cvttime(t2) - cvttime(t1)
}

它将GNU awk用于时间函数,请参见以下Perl示例:

use feature qw(say);
use strict;
use warnings;

use Text::CSV;
use Time::Piece;

my $csv = Text::CSV->new;
my $te = Time::Piece->strptime('01-OCT-14', '%d-%b-%y');
my $fn = 'Input.csv';
open (my $fh, '<', $fn) or die "Could not open file '$fn': $!\n";
chomp(my $head = <$fh>);
say "$head,Ageing-NoOfDays";
while (my $line = <$fh>) {
    chomp $line;
    if ($csv->parse($line)) {
        my $t = ($csv->fields())[2];
        my $tp = Time::Piece->strptime($t, '%d-%b-%y.%T');
        my $s = $te - $tp;
        say "$line," . $s->days;
    } else {
        warn "Line could not be parsed: $line\n";
    }
}
close($fh);
使用功能qw(比如说);
严格使用;
使用警告;
使用Text::CSV;
使用时间::件;
my$csv=文本::csv->新建;
我的$te=Time::Piece->strtime('01-10-14','%d-%b-%y');
my$fn='Input.csv';

打开(我的$fh,'非常感谢Hakon Haegland的输入,不幸的是我的办公室笔记本电脑中没有安装perl!!!Ed Morton,你真是一个有好东西的伟大人物,新脚本在Cygwin只花了16秒的时间,而旧脚本一行只需要50分钟!!!Ed Morton,我接受了答案并投了赞成票!!!
use feature qw(say);
use strict;
use warnings;

use Text::CSV;
use Time::Piece;

my $csv = Text::CSV->new;
my $te = Time::Piece->strptime('01-OCT-14', '%d-%b-%y');
my $fn = 'Input.csv';
open (my $fh, '<', $fn) or die "Could not open file '$fn': $!\n";
chomp(my $head = <$fh>);
say "$head,Ageing-NoOfDays";
while (my $line = <$fh>) {
    chomp $line;
    if ($csv->parse($line)) {
        my $t = ($csv->fields())[2];
        my $tp = Time::Piece->strptime($t, '%d-%b-%y.%T');
        my $s = $te - $tp;
        say "$line," . $s->days;
    } else {
        warn "Line could not be parsed: $line\n";
    }
}
close($fh);