combinando grep ignore e corresponde

0

Eu gostaria de fazer um arquivo para encontrar todas as instâncias do texto fn1 que não têm a palavra call na frente e imprimir quatro linhas antes e depois das correspondências (mesmo se as linhas ao redor tem a palavra call neles). Eu tentei

grep -A 4 -B 4 '[^call].+fn1'

mas não recebe nenhuma correspondência (presumivelmente por causa do [^call] ). Eu não posso simplesmente usar -v e canalizar isso para outro grep ou vice-versa, porque eu quero ver as linhas de texto ao redor. Eu acho que eu poderia usar -v em call , canalizar isso para grep fn1 e então canalizar essas linhas para outra instância do grep que combine as linhas inteiras com o contexto mas isso parece feio e pode ser muito lento se houver muitas correspondências.

Isso parece que deve ser simples, mas não tenho certeza. Alguma ajuda?

EDITAR:

Dados de amostra

main code
main code
more main code
call fn1(ii, jj)
even more main code
call fn2
still more main code

function fn1
call fn3
fn1 code
more fn1 code

Eu gostaria que o grep retutasse

call fn2
still more main code

function fn1
call fn3
fn1 code
more fn1 code

Eu quero que ele me mostre todas as instâncias onde fn1 é usado exceto quando está sendo chamado e eu não quero perder outras funções que estão sendo chamadas dentro do contexto.

    
por William Everett 03.12.2014 / 22:39

1 resposta

2

Negar expressões regulares não é fácil. Você pode usar lookbehinds negativos :

$ grep -C4 -P '(?<!call).*fn1' test.txt 
5-even more main code
6-call fn2
7-still more main code
8-
9:function fn1
10-call fn3
11-fn1 code
12-more fn1 code

Este grep usa expressões regulares no estilo Perl ( -P ) para procurar por qualquer instância de fun não precedida por call . E você pode combinar -A4 -B4 para obter -C4 .

    
por 04.12.2014 / 19:58