Compare sets de valores de dos files e imprima la salida en un tercer file usando awk

Tengo un problema al comparar dos files. Haré mi mejor esfuerzo para explicar. Tengo dos files f1 y f2 que tengo que comparar en base a dos sets, el parámetro (p) y el valor (v) .

Básicamente f1 contiene una list de valores y timestamp para cada uno de los parameters

f1.csv P,V,TS p1,12,10:10:00 p2,34,10:21:00 p1,12,10:21:00 p2,34,10:22:00 p1,60,10:35:00 p3,60,10:36:00 p4,22,10:38:00 p4,42,10:40:00 p1,60,10:41:00 p3,58,10:42:00 p2,55,10:45:00 p3,58,10:55:00 

El file f2 contiene el valor anterior / último y la timestamp para cada parámetro. Cada parámetro tiene solo una ocurrencia en este file. Para mayor claridad, RTS (Sello de time real) y UTS (Sello de time actualizado).

  f2.csv P,V,RTS,UTS p1,12,10:00:00,10:05:00 p2,34,10:07:00,10:15:00 p3,60,10:25:00,10:30:00 p4,22,10:30:00,10:32:00 

Ahora intentaré explicar la salida en dos partes. La primera parte es fácil: para similar (P, V) en f1 y f2, cambie el UTS con el último TS. Aquí está el pseudo código:

  for each (P, V) in f1 { #if value exists in f2 if ((P, V) exists in f2) { f2.RTS(P,V)=f2.RTS(P,V) f2.UTS(P, V) = f1.TS(P, V) } } 

Para el valor que existe en f2 y f1 primera parte del file o / p f3 en []: –

  f3.csv [ P,V,RTS,UTS p1,12,10:00:00,10:10:00 p2,34,10:07:00,10:21:00 p1,12,10:00:00,10:21:00 p2,34,10:07:00,10:22:00 p3,60,10:25:00,10:36:00 p4,22,10:30:00,10:38:00] 

La segunda parte es difícil. Se trata solo del file f1: valores que no existen en f2.

Para los valores de f1 (p4,42,10: 40: 00) (p2,55,10: 45: 00) que ocurren solo una vez y no están en f2, debe tener RTS = UTS = TS como se indica en el resultado que se muestra a continuación.

Ejemplo: -Para una sola ocurrencia

  p4,42,10:40:00,10:40:00 

Para valores (p3,58,10: 42: 00), (p3,58,10: 55: 00), (p1,60,10: 35: 00) (p1,60,10: 41: 00) que ocurren dos veces y no están en f2, la primera aparición debe tener RTS = UTS = TS y la segunda ocurrencia para el mismo (P, V) debe tener RTS = (TS de la primera aparición de (P, V)) y UTS = TS de segundo ocurrencia de (P, V).

Ejemplo: primera aparición (p1,60) en f1.

  p1,60,10:35:00,10:35:00 

Segunda aparición (p1,60) en f1

  p1,60,10:35:00,10:41:00 

La segunda parte del resultado esperado:

  f3.csv [ P,V,RTS,UTS p1,60,10:35:00,10:35:00 p4,42,10:40:00,10:40:00 p1,60,10:35:00,10:41:00 p3,58,10:42:00,10:42:00 p2,55,10:45:00,10:45:00 p3,58,10:42:00,10:55:00] 

La salida final se agrega a los files CSV de salida.

Gracias, cualquier ayuda será apreciada

Usé Perl aquí, ya que tiene estructuras de datos más flexibles (hash de hash de matrices).

 use strict; use warnings; use v5.10; use autodie; my (%f1, @order); open my $fh, "<", "f1.csv"; while (<$fh>) { next if $. == 1; chomp; my ($p, $v, $ts) = split /,/; push @{ $f1{$p}{$v} }, $ts; push @order, [$p, $v]; } close $fh; my %f2; open $fh, "<", "f2.csv"; while (<$fh>) { print if $. == 1; chomp; my ($p, $v, $rts, $uts) = split /,/; $f2{$p}{$v} = [$rts, $uts]; } close $fh; for my $key (@order) { my ($p, $v) = @$key; if (exists $f2{$p}{$v}) { my $uts = shift @{$f1{$p}{$v}} say join(",", $p, $v, $f2{$p}{$v}[0], $uts); } } my @remaining; for my $p (keys %f1) { for my $v (keys %{$f1{$p}}) { my ($rts, $uts) = @{$f1{$p}{$v}}; push @remaining, [$p, $v, $rts, $rts] if $rts; push @remaining, [$p, $v, $rts, $uts] if $rts and $uts; } } say for map {join ",", @{$_->[1]}} sort {$a->[0] cmp $b->[0]} map {[$_->[3], $_]} @remaining; 

Ejecutarlo produce:

 P,V,RTS,UTS p1,12,10:00:00,10:10:00 p2,34,10:07:00,10:21:00 p1,12,10:00:00,10:21:00 p2,34,10:07:00,10:22:00 p3,60,10:25:00,10:36:00 p4,22,10:30:00,10:38:00 p1,60,10:35:00,10:35:00 p4,42,10:40:00,10:40:00 p1,60,10:35:00,10:41:00 p3,58,10:42:00,10:42:00 p2,55,10:45:00,10:45:00 p3,58,10:42:00,10:55:00 

Aquí el código con alguna ayuda forma mi amigo. Solo para reference.

  #!/bin/awk -f BEGIN{ FS=","; OFS=","; } { if(NR==FNR) { a[var]=$1" "$2 ts[var]=$3 var++ }else if(NR>FNR) { b[sec]=$1" "$2 rt[sec]=$3 ut[sec]=$4 sec++ } } END{ #Code for first part of the o/p for(i=0;i<var;i++) { for(j=0;j<sec;j++) { if(!(a[i]<b[j]||a[i]>b[j])) { m[a[i]]=1 print a[i]" "rt[j]" "ts[i] } } } #Code for second part of the o/p for(i=0;i<var;i++) { if(m[a[i]]!=1) { h[a[i]]++ if(h[a[i]]==1) { rts[a[i]]=ts[i] print rts[a[i]] print a[i]" "ts[i]" "ts[i] } else{ print a[i]" "rts[a[i]]" "ts[i] } } } }