Extraer una aparición de un patrón del archivo

Extraer una aparición de un patrón del archivo

Tengo un archivo grande que contiene registros similares al que se muestra a continuación. Me gustaría encontrar todas las transacciones (TR#) que se vieron afectadas por el error. Necesito extraer una aparición de cada ID de TR#.

¿Cómo podría hacerlo?

    Apr 30 16:51:29.574 application.crit: [6104]:TR#14. Transaction send can not be sent. Error Code: 704
    Apr 30 16:51:29.574 application.crit: [6104]:TR#14. Transaction send can not be sent. Error Code: 704
    Apr 30 16:51:29.574 application.crit: [6104]:TR#14. Transaction send can not be sent. Error Code: 704
    Apr 30 16:51:29.574 application.crit: [6104]:TR#14. Transaction send can not be sent. Error Code: 704
    Apr 30 16:51:29.574 application.crit: [6104]:TR#238. Transaction send can not be sent. Error Code: 704
    Apr 30 16:51:29.574 application.crit: [6104]:TR#238. Transaction send can not be sent. Error Code: 704
    Apr 30 16:51:29.574 application.crit: [6104]:TR#238. Transaction send can not be sent. Error Code: 704
    Apr 30 16:51:29.574 application.crit: [6104]:TR#238. Transaction send can not be sent. Error Code: 704
    Apr 30 16:51:29.574 application.crit: [6104]:TR#238. Transaction send can not be sent. Error Code: 704
    Apr 30 16:51:29.574 application.crit: [6104]:TR#238. Transaction send can not be sent. Error Code: 704

Salida requerida:

    Apr 30 16:51:29.574 application.crit: [6104]:TR#14. Transaction send can not be sent. Error Code: 704
    Apr 30 16:51:29.574 application.crit: [6104]:TR#238. Transaction send can not be sent. Error Code: 704

Respuesta1

Esto es muy sencillo de hacer en awk:

$ awk 'c[$5]++==1' file 
Apr 30 16:51:29.574 application.crit: [6104]:TR#14. Transaction send can not be sent. Error Code: 704
Apr 30 16:51:29.574 application.crit: [6104]:TR#238. Transaction send can not be sent. Error Code: 704

O, en Perl:

$ perl -ane '$k{$F[4]}++==1 && print' file 
Apr 30 16:51:29.574 application.crit: [6104]:TR#14. Transaction send can not be sent. Error Code: 704
Apr 30 16:51:29.574 application.crit: [6104]:TR#238. Transaction send can not be sent. Error Code: 704

Lo anterior supone que el número antes de cada uno TR#IDes parte de la identificación. Si los números pueden cambiar pero solo necesitas uno de ellos, usa esto en su lugar:

$ awk -F'[:.]' 'c[$7]++==1' file 

o

$ perl -F'[:.]' -ane '$k{$F[6]}++==1 && print' file 

Respuesta2

Para obtener e imprimir la primera aparición de cada mensaje, intente

awk '! m[$5] {m[$5]=$0} END{for (e in m) print m[e]}'

Hice que las marcas de tiempo en su ejemplo fueran secuenciales para probarlo (y también corregí el valor de error truncado final):

$ awk '! m[$5] {m[$5]=$0} END{for (e in m) print m[e]}' tr2.log
Apr 30 16:51:27.574 application.crit: [6104]:TR#14. Transaction send can not be sent. Error Code: 704
Apr 30 16:51:31.574 application.crit: [6104]:TR#238. Transaction send can not be sent. Error Code: 704

Con agradecimiento a @terdon

Respuesta3

Aquí hay un script en Perl que hace lo que quieres:

#!/usr/bin/perl

#Read each line
while ($line = <>) {
  # Extract the transaction ID by looking for the text TR followed by digits
  ($trid) = $line =~ /.*(TR#\d+).*/ ;
  # If we've not seen the ID before, print it out
  unless ($trids{$trid}) {
    print $line;
  }
  # Remember the ID so we don't print it out again
  $trids{$trid} = 1;
}

Cuando lo llamo usando tu entrada, esto es lo que obtengo:

temeraire:ul jenny$ ./extract.pl in.txt 
    Apr 30 16:51:29.574 application.crit: [6104]:TR#14. Transaction send can not be sent. Error Code: 704
    Apr 30 16:51:29.574 application.crit: [6104]:TR#238. Transaction send can not be sent. Error Code: 704

Respuesta4

A través de GNU sed, robado deestePues contesta,

sed '$!N; /^\(.*\)\n\1$/!P; D' file

información relacionada