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

时间:2016-12-30 11:35:05

标签: awk

我需要打印记录开始日期($ 2和$ 3)之间经过的天数($ 4),直到记录($ 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  

2 个答案:

答案 0 :(得分:0)

您可以使用如下的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] )
      }

通过提供两次文件名来使用它:awk -f srcipt.awk yourfile yourfile

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

答案 1 :(得分:0)

您不需要2遍方法,因为您的输入是按ID排序的,因此您可以在每次ID更改时打印结果。

使用GNU awk for mktime():

$ 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