我需要在新字段的每个唯一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
答案 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