如何打印使用awk获得最小记录数所经过的天数?

如何打印使用awk获得最小记录数所经过的天数?,awk,Awk,我需要打印记录($4)的开始日期($2和$3)到记录($4)达到每个唯一ID($1)的最小值之间经过的天数。此外,我需要打印记录的起始值和记录的最小值之间的损失金额($4) 数据如下所示: 4 2016-07-19 06:09:50 546.5 4 2016-07-20 06:40:03 543.667 4 2016-07-21 05:43:18 539 4 2016-07-22 07:18:20 535 10 2016-07-20 08:0

我需要打印记录($4)的开始日期($2和$3)到记录($4)达到每个唯一ID($1)的最小值之间经过的天数。此外,我需要打印记录的起始值和记录的最小值之间的损失金额($4)

数据如下所示:

4   2016-07-19  06:09:50  546.5  
4   2016-07-20  06:40:03   543.667  
4   2016-07-21  05:43:18  539  
4   2016-07-22  07:18:20  535  
10  2016-07-20  08:08:45  488  
10  2016-07-21  07:32:35  490.5  
10  2016-07-23  06:01:58  470.5  
10  2016-07-24  08:26:02  472  
我需要看起来像这样

4   2016-07-19  06:09:50  546.5    3  11.5  
4   2016-07-20  06:40:03  543.667 3  11.5  
4   2016-07-21  05:43:18  539  3  11.5  
4   2016-07-22  07:18:20  535  3  11.5  
10  2016-07-20  08:08:45  488  3  17.5  
10  2016-07-21  07:32:35  490.5 3  17.5   
10  2016-07-23  06:01:58  470.5 3  17.5  
10  2016-07-24  08:26:02  472  3  17.5  

您可以使用如下所示的GNU awk脚本:

script.awk

FNR==NR { # first run, collect infos
        # split date and time, to generate a timestamp:
        split($2, d, "-")
        split($3, t, "[:]")
        ts=mktime( d[1] " " d[2] " " d[3] " " t[1] " " t[2] " " t[3] )

        if (!( $1 in start_T ) ) {
          start_T[ $1] = ts
          start_V[ $1] = $4
          min_V[ $1] = $4
          stop_T[ $1] = ts
        }
        if( $4 < min_V[ $1] ) {
            min_V[ $1] = $4
            stop_T[ $1] = ts
        }

        next; # skip next action block, during first run
      }

      { # this action block is used after first run
        printf("%s %5.0f %5.1f\n", $0, 
               (stop_T[$1] - start_T[$1]) / (60*60*24), # seconds per day
               start_V[$1] - min_V[$1] )
      }
FNR==NR{#第一次运行,收集信息
#拆分日期和时间,以生成时间戳:
拆分($2,d,“-”)
拆分($3,t,“[:]”)
ts=mktime(d[1]“d[2]”“d[3]”“t[1]”“t[2]”“t[3])
如果(!(起点为1美元)){
起始时间[$1]=ts
起始价[$1]=4美元
最小值V[$1]=4美元
停车费[$1]=ts
}
如果($4
它通过两次提供文件名来使用:
awk-f srcipt.awk yourfile yourfile


第一次运行从命令行上给出的第一个文件名收集信息(条件
FNR==NR
为true)。第二次运行在处理给定的第二个文件名时使用该信息

由于输入是按id排序的,所以每次id更改时,您都可以打印结果,因此不需要采用两次通过的方法

使用GNU awk for mktime():


它可以完美地处理从记录开始到记录最小值的损失。然而,达到最低记录(4美元)所需的天数并不理想。它只是计算一天的开始和结束记录之间的差异。我需要知道达到记录的最小值($4)所需的天数($2和$3)。
$ cat tst.awk
{ dayNr = int( mktime( gensub(/[-:]/," ","g",$2" "$3) ) / (24*60*60) ) }

$1 != prev {
    prtRows()
    begDayNr = dayNr
    begVal = minVal = $4
    prev = $1
}

{ rows[++numRows] = $0 }

$4 <= minVal {
    minVal = $4
    endDayNr = dayNr
}

END { prtRows() }

function prtRows() {
    for (rowNr=1; rowNr<=numRows; rowNr++) {
        print rows[rowNr], endDayNr - begDayNr, begVal - minVal
    }
    numRows = 0
}
$ awk -f tst.awk file
4   2016-07-19  06:09:50  546.5   3 11.5
4   2016-07-20  06:40:03   543.667   3 11.5
4   2016-07-21  05:43:18  539   3 11.5
4   2016-07-22  07:18:20  535   3 11.5
10  2016-07-20  08:08:45  488   3 17.5
10  2016-07-21  07:32:35  490.5   3 17.5
10  2016-07-23  06:01:58  470.5   3 17.5
10  2016-07-24  08:26:02  472 3 17.5