Grep para encontrar linhas começando no padrão A até que o padrão B seja correspondido

1

Eu tenho um log que contém bits como este:

[2012-04-16 15:16:43,827: DEBUG/PoolWorker-2] {'feed': {}, 'bozo': 1, 'bozo_exception': URLError(error(110, 'Connection timed out'),), 'entries': []}
[2012-04-16 15:16:43,827: ERROR/PoolWorker-2] get_entries
Traceback (most recent call last):
  File "/opt/myapp/app.py", line 491, in get_entries
    logging.getLogger(__name__).debug("Title: %s" % doc.title)
  File "build/bdist.linux-x86_64/egg/feedparser.py", line 423, in __getattr__
    raise AttributeError, "object has no attribute '%s'" % key
AttributeError: object has no attribute 'title'
[2012-04-16 15:16:43,828: INFO/MainProcess] Task myapp.do_task[4fe968ff-e069-4cfe-9a81-aece0d97c289] succeeded in 21.0481028557s: None

Gostaria de extrair as seções da seguinte forma:

  1. Quando uma linha contém "ERROR" ou "WARN", inicie a filtragem (e inclua esta linha)
  2. Quando a próxima linha que começa com "[" for encontrada, pare de filtrar (e não inclua essa linha).

Tenho certeza que isso é demais para o Grep, então como fazer isso?

(Ok, em vez de ser preguiçoso, eu descobri - vou postar minha solução.)

    
por Steve Bennett 18.04.2012 / 07:48

2 respostas

3

Isso funcionou para mim - não exatamente como descrito acima, mas perto o suficiente:

awk '/ERROR|WARN/,/DEBUG|INFO/ { if ($0 !~ /(DEBUG|INFO)/) { print } }' < logfile

Muito conveniente que o awk ofereça suporte a isso: /startpattern/,/stoppattern/ { } . Infelizmente, se o padrão de parada for correspondido na mesma linha que o padrão de início, ele imprimirá apenas essa linha, daí a necessidade de um padrão de parada diferente.

    
por 18.04.2012 / 07:50
2

Tente algo assim:

cat importantstuff.log | grep 'File .*, line .*, in .*' -B 1 -A 2

Não responde exatamente a pergunta, mas acho que ela realiza a tarefa.

Os sinalizadores -A e -B para linhas de contexto de controle do grep após ou antes de sua correspondência.

Isso funciona porque o grep agrupa correspondências adjacentes, então você acaba com tracebacks bem separados:

Traceback (most recent call last):
  File "sfquest.py", line 9, in b
    c()
  File "sfquest.py", line 15, in c
    d()
  File "sfquest.py", line 20, in d
    raise Exception('important information')
Exception: important information
--
Traceback (most recent call last):
  File "sfquest.py", line 9, in b
    c()
  File "sfquest.py", line 15, in c
    d()
  File "sfquest.py", line 20, in d
    raise Exception('important information')
Exception: important information
--
Traceback (most recent call last):
  File "sfquest.py", line 9, in b
    c()
  File "sfquest.py", line 15, in c
    d()
  File "sfquest.py", line 20, in d
    raise Exception('important information')
Exception: important information

Aqui está o código de exemplo que usei para gerar o exemplo do traceback:

import traceback                                                                

def a():                                                                        
    b()                                                                         

def b():                                                                        
    for i in range(10):                                                         
        try:                                                                    
            c()                                                                 
        except Exception, e:                                                    
            print 'bad stuff'                                                   
            print traceback.format_exc(e)                                       

def c():                                                                        
    d()                                                                         

def d():                                                                        
    for i in range(10):                                                         
        print 'random junk'                                                     
    raise Exception('important information')                                    

a()
    
por 29.11.2012 / 20:36