¿Cómo realizar un grep multilínea en varios archivos?

¿Cómo realizar un grep multilínea en varios archivos?

Estoy tratando de capturar este patrón dondequiera que aparezca en varios archivos de registro (Nota: estos patrones pueden variar mucho en tamaño, es decir, la cantidad de Blahs):

   Found an txt File
    Blah
    Blah
    10019874
    Blah
    Blah
    Processed File   

Usando esta línea de comando:

 pcregrep -M 'Found an.*(\n|.)*10019874.*(\n|.)*Processed' log_*.txt

Mi expresión regular se verificaREGEXACIONES AQUÍ

Estoy usando pcregrep con el indicador multilínea -M. Aparecerá en cualquier archivo de registro que comience con 'log_' y finalice con '.txt'. Cuando ejecuto este comando devuelve 'Error de segmentación'

¿Existe una forma mejor o más sencilla de hacer esto?

Respuesta1

Como dije en mi comentario, el comando que publicaste funciona bien en mi LMDE (pcregrep versión 8.31 2012-07-06). Sin embargo, dado que su expresión regular solo especifica parte de la cadena que está buscando, también puede hacer esto con normal grep:

grep -A 6 'Found an' log_*.txt | grep -C 3 10019874

Imprimirá -A 6la línea que coincide con la cadena pasada y las 6 líneas siguientes e -C 3imprimirá las 3circundantelíneas. El resultado final es exactamente el mismo que el pcregrepenfoque que estaba utilizando.


Si su patrón puede tener diferentes números de líneas, eso puede explicar el error de segmentación. Presumiblemente, en algunos de sus archivos, la sección coincidente es demasiado larga y provoca un error de falta de memoria. Una forma de solucionarlo sería un pequeño script:

perl -ne '$c=1 if /Found an/; ## set $c to 1 if this line matches 'Found on'
          if($c){               ## If $c is defined and non-0
            push @F,$_;         ## Add the current line to the @F array
            $c++ if /10019874/; ## Increment $c if this line matches '10019874'
            if(/Processed/){    ## If this line matches 'Processed'
                print "@F" if $c>1; ## Print the contents of @F if $c is >1
                @F=""; $c=0;         ## Empty @F, set $c to 0.
            }
           }' log_*.txt 

Lo mismo que una sola línea:

perl -ne '$c=1 if /Found an/; if($c){push @F,$_; $c++ if /10019874/; if(/Processed/){print "@F" if $c>1; @F=""; $c=0;}}' log_*txt 

información relacionada