使用awk基于具有日期和时间的数据文件来插入数据列

时间:2016-09-30 13:00:53

标签: awk gawk

以下文件包含多个列,其中包含日期,时间和不完整的数据集,如图所示使用简单文件

# Matrix.txt
13.09.2016:23:44:10;;4.0
13.09.2016:23:44:20;10.0;
13.09.2016:23:44:30;;
13.09.2016:23:44:40;30.0;7.0

如何使用awk对每列进行线性插值以获取缺失的数据:

# Output.txt
13.09.2016:23:44:10;0.0;4.0
13.09.2016:23:44:20;10.0;5.0
13.09.2016:23:44:30;20.0;6.0
13.09.2016:23:44:40;30.0;7.0

1 个答案:

答案 0 :(得分:0)

这是Gnu awk中的一个解决方案。它为第一个给定的数据文件运行两次,记住第一个和最后一个数据点( y 1 ,y 2 )及其时间戳( x 2 ,x 2 ),计算点的斜率( k =(y 2 -y < sub> 1 )/(x 2 -x 1 )并且对空元素进行插值和外推((y =(X <子> 1 -x)+ Y <子> 1 的)。

这不是万无一失的,它不会检查是否为零除或是否有两个斜坡或任何其他检查点。

$ cat inexpolator.awk
BEGIN {
    FS=OFS=";"
    ARGC=3; ARGV[2]=ARGV[1]        # run it twice for first file
}
BEGINFILE {                        # on the second round
        for(i in p)                # compute the slopes
            k[i]=(y2[i]-y1[i])/(x2[i]-x1[i])
}
{
    split($1,a,"[:.]")             # reformat the timestamp
    ts=mktime(a[3] " " a[2] " " a[1] " " a[4] " " a[5] " " a[6])
}
NR==FNR {                          # remember first and last points for slopes
    for(i=2;i<=NF;i++) {
        p[i]
        if(y1[i]=="") { y1[i]=$i; x1[i]=ts }
        if($i!="") { y2[i]=$i; x2[i]=ts }
    }
    next                           # only on the first round
}
{                                  # reformat ts again for output
    printf "%s", strftime("%d.%m.%Y:%H:%M:%S",ts) OFS  # print ts
    for(i=2;i<=NF;i++) {
        if($i=="") $i=k[i]*(ts-x1[i])+y1[i]            # compute missing points
        printf "%.1f%s", $i, (i<NF?OFS:ORS)            # print points
    }
}

运行它:

$ awk -f inexpolator.awk Matrix.txt
13.09.2016:23:44:10;0.0;4.0
13.09.2016:23:44:20;10.0;5.0
13.09.2016:23:44:30;20.0;6.0
13.09.2016:23:44:40;30.0;7.0