Faça a operação nas linhas em um fluxo e retenha o contexto

0

Imagine o seguinte problema: Eu tenho um log padrão do Apache. Quero filtrar os URLs de solicitação com uma determinada palavra-chave. Simples, nós usamos,

$ grep "keyword" somedomain-access.log

Isso funciona bem, mas não é robusto, ou seja, não funciona como exigido em 100% dos casos. Imagine nossa palavra-chave sendo "GET", (dependendo do site) quase todas as linhas seriam correspondidas pelo comando grep.

Nós fazemos alguns pré-processamentos fazendo:

$ cut -d" " -f['i'th field containing the url] somedomain-access.log | 
    grep "keyword"

Isso funciona um pouco melhor, mas agora eu perco todas as informações de contexto, ou seja, os outros campos que eu joguei fora com o comando cut .

Agora, esta questão em geral está me mordendo mais e mais. É claro que você pode usar o awk neste caso específico, mas geralmente, no caso geral, um comando awk não é suficiente.

Em idiomas que não são de shell, basta verificar o membro de um objeto e fazer sua operação. Então, usando nosso exemplo de log do Apache novamente, leve isso no Scala,

> // Preprocessed list of apache log into 'records'
> val records = List(AccessLogRecord(...), AccessLogRecord(...), ...)
> val recordsWithKeyword = records.filter(_ => _.request == "keyword")

O resultado ainda é uma lista onde cada item, neste caso, AccessLogRecord, ainda tem todas as informações de contexto, como data, código HTTP, etc.

Como podemos conseguir o mesmo na linha de comando usando pipes, redirecionamento, etc; sem depender de aplicativos específicos como awk ?

    
por hbogert 15.01.2017 / 17:26

0 respostas