2016-12-27 4 views
1

Мне нужно распечатать разницу (в днях) в (6 долларов США) между начальной и конечной датой записей для каждого уникального идентификатора (5 долларов США) в новом поле.
данных выглядит следующим образомКак рассчитать разницу начальных и конечных дат с помощью awk

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

[Это] (http://stackoverflow.com/questions/41247157/ как-может-я-вычислять-различие между-records-at-the-begin-and-end-of-a). –

+1

Кажется, что тот же вопрос задавали в другом месте: http://unix.stackexchange.com/questions/333235/how-can-i-get-the-difference-in-days-using-awk/333243#333243 –

ответ

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.

РЕДАКТИРОВАТЬ: Это предполагает, что есть только 2 из каждых уникальных идентификаторов в поле $5. Когда первое обнаружение идентификатора найдено, дата в поле $6 (и только часть даты) преобразуется в секунды и сохраняется в массиве a[$5]. Когда следующий найден, время, хранящееся до a[$5], вычитается из более позднего найденного времени и сохраняется до a[$5]. Если имеется более двух вхождений , то уникальный идентификатор $5 раз в a[$5] вычитается из последнего найденного времени и приводит к хаосу.

+1

молодцы , Я не думал, что это был триумф. Если бы у OP был лучший формат файла, я бы решил использовать Python для решения этой проблемы. – NinjaGaiden

+0

@James Brown. Когда я попробовал команду для данных данного образца, я получил отличный от вас. Кроме того, принимает ли команда учетные записи в другие дни между датой начала и окончания записей? у моего набора данных есть много записей о датах между датами начала и окончания каждого уникального идентификатора. Вот проблема, которую я получил, когда я печатаю команду – Alula

+0

, ее не совсем то, что вы нашли – Alula

0

Я знаю, что вы просите решение awk, но, возможно, рассмотрите решение Python/Pandas для этого.

источник Преобразовать файл

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

Затем используйте панд

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) 

анс выглядит следующим образом

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 
Смежные вопросы