如何使用awk计算起始和结束日期差异

时间:2016-12-27 10:57:15

标签: awk

我需要在新字段的每个唯一ID($ 5)的记录的开始日期和结束日期之间打印($ 6)的差异(以天为单位)。
数据看起来像这样

7  65  2    5   32070  2010-12-14    13:25:30    
7  82  2    10  41920  2010-12-14    11:30:45  
7  83  1    67  29446  2010-12-14    04:15:25      
7  81  1    47  32070  2011-5-11     08:14:20  
7  83  1    67  29446  2011-6-22     07:13:24
7  82  2    10  41920  2011-5-14     06:15:25  

我需要看到如下:

7  65  2    5   32070  2010-12-14    13:25:30   147  
7  82  2    10  41920  2010-12-14    11:30:45   150  
7  83  1    67  29446  2010-12-14    04:15:25   189  
7  81  1    47  32070  2011-5-11     08:14:20   147  
7  83  1    67  29446  2011-6-22     07:13:24   189  
7  82  2    10  41920  2011-5-14     06:15:25   150 

我使用了以下代码但是给了我错误消息。如果你有其他选择,你能帮我吗?

awk '{  
       split($6,arr,"-")  
      a=sprintf("%s %s %s 0 0 0",arr[1], arr[2], arr[3])  
      d=mktime(a)    
      delta[$5]=delta[$5] " " d  
     }   
   END {for(i in delta) {print i, delta[i]}  }'  filename > tmp.dat  

awk '{  
     if (FILENAME=="tmp.dat" )  
     {   
       delta[$1]=$0;   
       next  
     }  
     if (FILENAME=="filename")  
     {   
       a="-1"  
       if($5 in delta)  
      {  
        cnt=split(delta[$5],arr)  
       if(cnt==3)  
       {  
         a=arr[3] - arr[2]  
         a/=86400  
         a=int(a)  
       }  
       }  
      print $0, a        
      next  
       }  
        }' tmp.dat filename     

2 个答案:

答案 0 :(得分:2)

在awk中。源文件读入两次。首先计算时间差,在第二个记录上输出附加的时间差异。

$ awk 'NR==FNR {
           c = "date -d \""$6 "\" +%s";   # use system date for epoch time seconds
           c | getline d;                 # execute command in c var, output to d 
           a[$5] = (($5 in a) ? d-a[$5] : d); # set or subtract from array
           next                           # skip to next record
       } {                                # for the second go:
           # $1=$1;                       # uncomment to clean trailing space
           print $0, int(a[$5]/86400)     # print record and time  difference
       }' file file
7  65  2    5   32070  2010-12-14    13:25:30     147
7  82  2    10  41920  2010-12-14    11:30:45   150
7  83  1    67  29446  2010-12-14    04:15:25       189
7  81  1    47  32070  2011-5-11     08:14:20   147
7  83  1    67  29446  2011-6-22     07:13:24 189
7  82  2    10  41920  2011-5-14     06:15:25   150

时差之前的间距因您的数据在$NF之后有尾随空格而有所不同。您可以在$1=$1;之前使用print修剪它。

编辑:它希望字段$5中每个唯一ID 只有2个。找到ID的第一个出现时,字段$6中的日期(仅日期部分)将转换为秒并存储到数组a[$5]。找到下一个时间后,从后面找到的时间中减去存储到a[$5]的时间并存储到a[$5]。如果$5中出现的{em>唯一ID a[$5] 时间超过2次,则会从上次找到的时间中减去该时间并导致混乱。

答案 1 :(得分:0)

我知道你要求提供awk解决方案,但也许可以考虑使用Python / Pandas解决方案。

转换源文件

awk '{ $1 = $1; $0 = $0; print }' OFS=, tmp.dat > tmp1.dat

然后使用pandas

import pandas as pd                                                                                                                                                                            
import numpy as np                                                                                                                                                                                   


df=pd.read_csv("/tmp/tmp1.dat",names=[0,1,2,3,4,5,6],dtype={1:str,
                                                            2:str,
                                                            3:str,
                                                            4:str,
                                                            5:str,
                                                            6:str})                                                                                                                                          
df[5]=pd.to_datetime((df[5].astype(str)+" "+df[6].astype(str))); del df[6] 

for i,j in df.groupby(4):
    df.ix[df[4]==i,'days']=j[5].diff().fillna(method='bfill')

df['days']=(df['days']/np.timedelta64(1,'D')).astype(int)

df.to_csv("/tmp/ans)

ans看起来像这样

7,65,2,5,32070,2010-12-14 13:25:30,147
7,82,2,10,41920,2010-12-14 11:30:45,150
7,83,1,67,29446,2010-12-14 04:15:25,190
7,81,1,47,32070,2011-05-11 08:14:20,147
7,83,1,67,29446,2011-06-22 07:13:24,190
7,82,2,10,41920,2011-05-14 06:15:25,150