Remover linhas de um arquivo que existe em outro arquivo com timestamp mais recente

1

Eu tenho dois arquivos exatamente no mesmo formato e os mesmos dados, exceto para uma coluna.
Exemplo de linha do arquivo 1:

"1/30/2017 11:14:55 AM",Valid customer,jim.smith,NY,1485771295    

Exemplo de linha do arquivo 2:

"1/26/2017 8:02:01 PM",Valid customer,jim.smith,NY,1485457321  

É claro que os arquivos têm outras linhas, mas o que me interessa é o seguinte: Eu quero remover do arquivo 2 todas as linhas que são sobre a mesma entidade, ou seja, $3 e existem no arquivo 1 com um carimbo de data e hora posterior e manter o resto.
Nas linhas de exemplo, você pode ver que a linha no arquivo 1 é mais nova, como vemos na sequência de data da coluna 1. Agora, o último inteiro na linha é a época real da coluna 1, portanto, essa coluna pode ser usada, por exemplo, comparando as datas e a classificação.
Eu posso conseguir isso fazendo o script, por exemplo, no perl, algo como o seguinte:

#!/usr/bin/perl  

use strict;  
use warnings;  
my $file_a = "file1";
my $file_b = "file2";

open my $file_a_h, $file_a or die "Could not open $file_a";  

sub timestamp_users {  
    my ($fh) = @_;  
    my %recs;   

   while ( my $line =<$fh> ) {    
        my @items = split ",", $line;  
        my $user = $items[3];  
        $recs{$user} = $items[5];    
    }  
    return \%recs;    
}    

my $file_a_recs = timestamp_users($file_a_h);  

close $file_a_h;  

open my $file_b_h, $file_b or die "Could not open $file_b";  

my $file_b_recs = timestamp_users($file_b_h);    
close $file_b_h;  

my $count = 0;
while (my ($user, $last_time) = each %$file_b_recs) {  
    if(exists $file_a_recs->{$user} && $last_time >= $file_a_recs->{$user}) {
        ++$count;  
        'echo $user >> result.txt';    

    }
}
print "count: $count\n";    

Nesse caso, eu apenas exibo os usuários e, em seguida, preciso fazer um grep -v no arquivo_b para descobrir as linhas de que preciso.

Mas existe uma maneira de fazer isso usando ferramentas de linha de comando?
Essa abordagem parece muito complicada para mim.

Atualização:

Exemplo de linha do arquivo 1:

"1/30/2017 11:14:55 AM",Valid customer,jim.smith,NY,1485771295        
"1/26/2017 5:06:11 AM",New customer,john.doe,CA,1485403571    
"1/30/2017 4:14:30 AM",New customer,tim.jones,CO,1485746070    

Exemplo de linha do arquivo 2:

"1/26/2017 8:02:01 PM",Valid customer,jim.smith,NY,1485457321    
"1/30/2017 11:09:36 AM",New customer,tim.jones,CO,1485770976   
"1/30/2017 11:14:03 AM",New customer,john.doe,CA,1485771243  
"1/30/2017 11:13:53 AM",New customer,bill.smith,CA,1485771233  

Resultado esperado:

"1/30/2017 11:14:03 AM",New customer,john.doe,CA,1485771243    
"1/30/2017 11:09:36 AM",New customer,tim.jones,CO,1485770976   
"1/30/2017 11:13:53 AM",New customer,bill.smith,CA,1485771233  
    
por Jim 04.02.2017 / 14:13

1 resposta

1

Para obter a versão mais recente de cada linha nos dois arquivos:

$  cat file1 file2 | sort -t',' -k3,3 -k5,5nr | sort -t',' -u -k3,3 -o newest

Isso concatena os arquivos e classifica os registros com os campos do campo 3 e 5 como a chave de classificação. Isso classifica o arquivo concatenado para que o registro mais recente de cada pessoa seja o primeiro (graças ao timestamp na última coluna). A última classificação usa o campo 3 como chave de classificação e faz uma classificação única com base nesse campo. Isso deixará apenas o registro mais recente para cada pessoa no arquivo newest .

Em seguida, criamos o complemento das linhas em newest , ou seja, todos os registros nos dois arquivos que são mais antigos que o registro mais recente para cada pessoa:

$ cat file1 file2 | grep -v -F -x -f newest >older

O grep faz uma correspondência de sequência fixa ( -F ) em linhas completas ( -x ) e retorna todas as linhas que não correspondem ( -v ) a nada em newest . Essas linhas são armazenadas em older .

O último passo é remover qualquer linha de file2 presente no arquivo older :

$ grep -v -F -x -f older file2 >new-file2
    
por 04.02.2017 / 15:02