Estou tentando capturar esse padrão onde quer que ele ocorra em vários arquivos de log (Observação: esses padrões podem variar muito em tamanho, ou seja, na quantidade de Blahs):
Found an txt File
Blah
Blah
10019874
Blah
Blah
Processed File
Usando esta linha de comando:
pcregrep -M 'Found an.*(\n|.)*10019874.*(\n|.)*Processed' log_*.txt
Meu regex verificaREGEX AQUI
Estou usando pcregrep com o sinalizador multilinha -M. Ele estará em qualquer arquivo de log que comece com 'log_' e termine com '.txt'. Quando executo este comando ele retorna 'Falha de segmentação'
Existe uma maneira mais simples/melhor de fazer isso?
Responder1
Como eu disse em meu comentário, o comando que você postou funciona bem no meu LMDE (pcregrep versão 8.31 06/07/2012). No entanto, como sua regex especifica apenas parte da string que você está procurando, você também pode fazer isso com normal grep
:
grep -A 6 'Found an' log_*.txt | grep -C 3 10019874
Ele -A 6
imprimirá a linha correspondente à string passada e as 6 linhas seguintes e -C 3
imprimirá as 3em torno dalinhas. O resultado final é exatamente igual à pcregrep
abordagem que você estava usando.
Se o seu padrão puder ter números diferentes de linhas, isso pode explicar a falha de segmento. Presumivelmente, em alguns dos seus arquivos, a seção correspondente é muito longa e causa um erro de falta de memória. Uma maneira de contornar isso seria um pouco de 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
A mesma coisa que um forro:
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