Obtenha as primeiras ocorrências do grupo no log

Obtenha as primeiras ocorrências do grupo no log

Tenho um log enorme que pretendo filtrar apenas para a primeira ocorrência de cada grupo. No log “grupo” está tudo após o timestamp na primeira coluna.

Veja um exemplo:

Mar 06 16:34:00.378;sample07;0.1.0-3af8c384;WXHXdaYrHcVQYvLR;
Mar 06 16:34:02.856;sample03;0.1.0-3af8c384;Y2XdtYN2of7JUc4b;
Mar 06 16:34:03.314;sample07;0.1.0-3af8c384;WXHXdaYrHcVQYvLR;
Mar 06 16:34:03.525;sample07;0.1.0-3af8c384;WXHXdaYrHcVQYvLR;
Mar 06 16:34:04.773;sample01;0.1.0-3af8c384;A6OZwO2e9wV6Z1PI;
Mar 06 16:34:04.997;sample04;0.1.0-3af8c384;9azoPOnrcabk8Lfv;
Mar 06 16:34:05.241;sample04;0.1.0-3af8c384;9azoPOnrcabk8Lfv;
Mar 06 16:34:06.546;sample04;0.1.0-3af8c384;9azoPOnrcabk8Lfv;
Mar 06 16:34:06.671;sample08;0.1.0-3af8c384;WXHXdaYrHcVQYvLR;
Mar 06 16:34:07.394;sample05;0.1.0-3af8c384;JJYhwRHyTMNKM2DI;
Mar 06 16:34:07.569;sample05;0.1.0-3af8c384;JJYhwRHyTMNKM2DI;
Mar 06 16:34:09.120;sample05;0.1.0-3af8c384;JJYhwRHyTMNKM2DI;
Mar 06 16:34:09.371;sample05;0.1.0-3af8c384;JJYhwRHyTMNKM2DI;
Mar 06 16:34:09.534;sample06;0.1.0-3af8c384;tasghviiAoMrPfaZ;
Mar 06 16:34:09.662;sample04;0.1.0-3af8c384;Y2XdtYN2of7JUc4b;
Mar 06 16:34:09.822;sample07;0.1.0-3af8c384;WXHXdaYrHcVQYvLR;

O resultado esperado é:

Mar 06 16:34:00.378;sample07;0.1.0-3af8c384;WXHXdaYrHcVQYvLR;
Mar 06 16:34:02.856;sample03;0.1.0-3af8c384;Y2XdtYN2of7JUc4b;
Mar 06 16:34:04.773;sample01;0.1.0-3af8c384;A6OZwO2e9wV6Z1PI;
Mar 06 16:34:04.997;sample04;0.1.0-3af8c384;9azoPOnrcabk8Lfv;
Mar 06 16:34:06.671;sample08;0.1.0-3af8c384;WXHXdaYrHcVQYvLR;
Mar 06 16:34:07.394;sample05;0.1.0-3af8c384;JJYhwRHyTMNKM2DI;
Mar 06 16:34:09.534;sample06;0.1.0-3af8c384;tasghviiAoMrPfaZ;
Mar 06 16:34:09.662;sample04;0.1.0-3af8c384;Y2XdtYN2of7JUc4b;

Consegui as combinações exclusivas sem o carimbo de data/hora:

cut -d";" -f2- small_log.log | sort | uniq

Mas como faço para juntá-lo novamente para obter o carimbo de data/hora? Também não acho que isso sort | uniqserá bem dimensionado para milhões de linhas.

Responder1

Eu faria isso no awk:

$ awk -F';' '++seen[$2$3$4]==1' file 
Mar 06 16:34:00.378;sample07;0.1.0-3af8c384;WXHXdaYrHcVQYvLR;
Mar 06 16:34:02.856;sample03;0.1.0-3af8c384;Y2XdtYN2of7JUc4b;
Mar 06 16:34:04.773;sample01;0.1.0-3af8c384;A6OZwO2e9wV6Z1PI;
Mar 06 16:34:04.997;sample04;0.1.0-3af8c384;9azoPOnrcabk8Lfv;
Mar 06 16:34:06.671;sample08;0.1.0-3af8c384;WXHXdaYrHcVQYvLR;
Mar 06 16:34:07.394;sample05;0.1.0-3af8c384;JJYhwRHyTMNKM2DI;
Mar 06 16:34:09.534;sample06;0.1.0-3af8c384;tasghviiAoMrPfaZ;
Mar 06 16:34:09.662;sample04;0.1.0-3af8c384;Y2XdtYN2of7JUc4b;

A ação padrão awkquando algo é avaliado como verdadeiro é imprimir a linha atual. A expressão ++seen[$1$2}torna o segundo e terceiro campos a chave na matriz associativa seene aumenta seu valor em um. Portanto, ++seen[$2$3$4]==1só será verdade na primeira vez que esta combinação do 2º e 3º campo for vista.

É basicamente uma forma abreviada de escrever:

awk -F';' '{ 
             seen[$2$3$4]++; 
             if(seen[$2$3$4] == 1){
                print
             }
            }' file 

Alternativamente, você também pode fazer isso como tentou, com sort. Você nem precisa cut, basta sortordenar nos campos 2 a 4 e retornar resultados exclusivos:

$ sort -t';' -k2,4 -u file 
Mar 06 16:34:04.773;sample01;0.1.0-3af8c384;A6OZwO2e9wV6Z1PI;
Mar 06 16:34:02.856;sample03;0.1.0-3af8c384;Y2XdtYN2of7JUc4b;
Mar 06 16:34:04.997;sample04;0.1.0-3af8c384;9azoPOnrcabk8Lfv;
Mar 06 16:34:09.662;sample04;0.1.0-3af8c384;Y2XdtYN2of7JUc4b;
Mar 06 16:34:07.394;sample05;0.1.0-3af8c384;JJYhwRHyTMNKM2DI;
Mar 06 16:34:09.534;sample06;0.1.0-3af8c384;tasghviiAoMrPfaZ;
Mar 06 16:34:00.378;sample07;0.1.0-3af8c384;WXHXdaYrHcVQYvLR;
Mar 06 16:34:06.671;sample08;0.1.0-3af8c384;WXHXdaYrHcVQYvLR;

E se você precisar classificá-los por carimbo de data e hora, basta passar sortnovamente:

$ sort -t';' -k2,4 -u file  | sort
Mar 06 16:34:00.378;sample07;0.1.0-3af8c384;WXHXdaYrHcVQYvLR;
Mar 06 16:34:02.856;sample03;0.1.0-3af8c384;Y2XdtYN2of7JUc4b;
Mar 06 16:34:04.773;sample01;0.1.0-3af8c384;A6OZwO2e9wV6Z1PI;
Mar 06 16:34:04.997;sample04;0.1.0-3af8c384;9azoPOnrcabk8Lfv;
Mar 06 16:34:06.671;sample08;0.1.0-3af8c384;WXHXdaYrHcVQYvLR;
Mar 06 16:34:07.394;sample05;0.1.0-3af8c384;JJYhwRHyTMNKM2DI;
Mar 06 16:34:09.534;sample06;0.1.0-3af8c384;tasghviiAoMrPfaZ;
Mar 06 16:34:09.662;sample04;0.1.0-3af8c384;Y2XdtYN2of7JUc4b;

informação relacionada