Usando Grep -o ou Sed / Awk para pegar o trecho do meio da string

4

Estou assistindo ao tráfego de log e vejo o abuso regular dos vários mecanismos de pesquisa de imagens, especialmente o Bing.

URL de exemplo:

http://www.bing.com/images/search?q=dagger+genesis+solo&view=detailv2&&&id=C65E811DFE01FB11258D2EB4F516F3DD8F09049C&selectedIndex=4&ccid=ffC0NVO8&simid=608046582336849763&thid=JN.XnLfF7qiZGwjJzTCR6f7ZQ&mode=overlay

Eu quero retirar a pesquisa em si, o "solo da gênese da adaga".

Eu posso

grep -o '=*' 

mas isso deixa o sinal = e tudo o que segue a pesquisa.

Eu quero pegar tudo entre "search? q=" e o primeiro "&" o final da última palavra precedido por um "+".

Eu poderia chegar lá de uma maneira muito longa e complicada usando o awk ou o cut para remover o máximo possível de minha string e usar separadores de campo especificados para colocar cada palavra em sua própria coluna e depois imprimir apenas essas colunas . Mas mesmo esse método não seria consistente, uma vez que as pesquisas podem ser de qualquer tamanho e incluir praticamente qualquer caractere.

Estou pensando que há uma maneira muito mais fácil embora. Idéias?

Meu objetivo final é despir as consultas de pesquisa e agrupá-las em entradas exclusivas.

    
por user112802 05.06.2015 / 04:35

4 respostas

3

Você pode fazer

sed 's/^.*search?q=\([^&]*\)&.*//' file

O que isso faz é uma correspondência não voraz entre o search?q= e o &

Quais saídas

dagger+genesis+solo

Se você quiser substituir os sinais + por espaços,

sed 's/^.*search?q=\([^&]*\)&.*//;s/+/ /g' file

Quais saídas

dagger genesis solo
    
por 05.06.2015 / 04:51
4

Se o grep do seu sistema for compatível com o modo PCRE, você poderá usar lookarounds (afirmações de tamanho zero) para selecione caracteres entre search?q= e &

grep -Po '(?<=search\?q=).+?(?=&)'

Usando o modificador não ganancioso, ? entre faz com que o jogo pare no primeiro & .

    
por 05.06.2015 / 04:51
2

com sed :

sed 's/\([^=&]*.\)\{2\}&.*//' <<""
http://www.bing.com/images/search?q=dagger+genesis+solo&view=detailv2&&&id=C65E811DFE01FB11258D2EB4F516F3DD8F09049C&selectedIndex=4&ccid=ffC0NVO8&simid=

Quando uma contagem de ocorrências é especificada para uma correspondência com referência anterior, sed deve referenciar apenas a correspondência especificada. Então, no exemplo acima, a referência retorna apenas

dagger+genesis+solo
    
por 05.06.2015 / 06:53
1

Usando as asserções grep look-behind e look-ahead:

grep -oP "\=\K.*(?=\&view)"

Aqui,

\K          ==>  zero-width look-behind assertion
(?=\&view)  ==>  zero-width look-ahead assertion

Portanto, somente a parte entre \= e &view , ou seja, .* , é impressa.

    
por 05.06.2015 / 04:52

Tags