Remova o texto que não quero

5

Eu tenho um grande arquivo html na minha área de trabalho que parece

src="http://images.alaablubnan.com/images/Balls/20.jpg"
alt="http://images.alaablubnan.com/images/Balls/20.jpg"/></a></td><td><a
href="http://images.alaablubnan.com/images/Balls/32.jpg"
target="_blank"><img
src="http://images.alaablubnan.com/images/Balls/32.jpg"
alt="http://images.alaablubnan.com/images/Balls/32.jpg"/></a></td><td><a
href="http://images.alaablubnan.com/images/Balls/30.jpg"
target="_blank"><img
src="http://images.alaablubnan.com/images/Balls/30.jpg"
alt="http://images.alaablubnan.com/images/Balls/30.jpg"/></a></td></tr><tr><td><table><tr><td>webpage/url</td><td>http://www.playlebanon.com/webservices/website/lotto/PopUps/HistoryDetail.aspx?t=1405536730503&FromDraw=1&ToDraw=1213&Draw=0</td></tr></table></td><td>2</td><td>complete
lotto results</td><td>complete lotto results</td><td>2</td><td><a
href="http://www.playlebanon.com/webservices/website/lotto/PopUps/HistoryDetail.

Se possível, quero:

  • obtenha todos os arquivos .jpg, remova todo o código html (é 1.jpg, 2.jpg ... para 42.jpg)
  • Desejo remover a extensão .jpg
  • Eu quero que cada linha de números tenha apenas 7 números e insira uma nova linha
por Lynob 25.07.2014 / 11:20

2 respostas

11

Este não é um trabalho particularmente bom para sed , mas aqui vai:

sed -nr 's#.*/([^"]+).jpg.*##p' file 

O texto acima mostra uma lista de números, um por linha:

20
20
32
32
32
30
30
30

Agora, é realmente possível colocar todos esses itens na mesma linha com 7 números por linha usando sed , mas não vale a pena o esforço. Apenas use as ferramentas padrão * nix:

$ echo $(sed -nr 's#.*/([^"]+).jpg.*##p' file | tr $'\n' ' ') | fold -sw 21
20 20 32 32 32 30 30 
30

Ou, se você quiser remover duplicatas:

echo $(sed -nr 's#.*/([^"]+).jpg.*##p' file | sort -u | tr $'\n' ' ')
20 30 32

Explicação

O comando sed usa alguns truques:

  • -n : não imprima linhas por padrão.
  • -r : ativar expressões regulares estendidas, isso nos permite usar ( ) para grupos de captura sem precisar fugir do parênteses e + para "um ou mais".
  • s#from#to# : enquanto o operador de substituição padrão em sed e outras ferramentas semelhantes é s/from/to/ , você pode um delimitador não padrão para incluir / no padrão. Nesse caso, estou usando # , mas você também pode usar outra coisa como s|from|to| .
  • s#.*/([^"]+).jpg.*##p : isso vai combinar tudo desde o começo da linha até um / e, em seguida, captura o trecho mais longo de caracteres que não são " até .jpg . Este é o nome do arquivo menos extensão. O nome do arquivo é capturado nos parênteses e a linha inteira (por causa do .* em ambos os lados) será substituída pelo padrão capturado ( ). O p no final significa que ele imprimirá as linhas onde a substituição foi bem-sucedida.

Pessoalmente, eu teria feito tudo isso com perl em primeiro lugar:

$ perl -e '@k=grep(s/.*\/([^"]+).jpg.*//s,<>); print "@k[0..6]\n@k[7..$#k]\n"' file 
20 20 32 32 32 30 30
30

Ou, para um arquivo maior:

$ perl -e '@k=grep(s/.*\/([^"]+).jpg.*//s,<>); for($i=0;$i<=$#k;$i+=7){print "@k[$i..$i+7]\n"}' file 
20 20 32 32 32 30 30 30
30       

Ou grep mesmo:

$ echo $(grep -oP '[^/]+(?=.jpg)' file | tr $'\n' ' ' ) | fold -w 21
20 20 32 32 32 30 30 
30

Ou, roubando a idéia inteligente de xargs do Olli:

$ grep -oP '[^/]+(?=.jpg)' file |  xargs -n7 echo
20 20 32 32 32 30 30
30
    
por terdon 25.07.2014 / 12:17
8

Suponho que você esteja tentando obter algum tipo de resultado. Neste exemplo, existem apenas três bolas e podemos extraí-las pesquisando por Balls/<one-or-many-digits> e agrupamento (o \(..\) construct) em torno do número e, em seguida, substituindo o lote inteiro por esse grupo (o é uma referência ao primeiro grupo).

$ sed -n 's/.*Balls\/\([0-9]\+\).*//gp' htmlfile | uniq | xargs -n7 echo
20 32 30

sed está passando por essa linha por linha. Eu estou pedindo para combinar e substituir tudo na linha (é por isso que limitamos cada final com .* - "qualquer quantia de qualquer coisa") com qualquer coisa que corresponda ao grupo. Os -n e /p são usados juntos para não serem impressos, a menos que a linha seja uma correspondência e o /g significa que ela continuará correspondendo até atingir o final do arquivo.

É um exemplo bastante complicado se você é novo em expressões regulares.

Estou passando por uniq porque há muita duplicação acontecendo aqui.

Estou usando | xargs -n7 echo no final para agrupar os argumentos 7 e passá-los para echo . Não há 7 bolas aqui, por isso só está mostrando 3.

Ele provavelmente fica mais lento, mas você pode ter uma expressão um pouco mais legível se usar a sintaxe estendida -r para sed :

sed -nr 's/.*Balls\/([0-9]+).*//gp' htmlfile | ...

Faz a mesma coisa, sem que alguns dos olhares confusos escapem.
Provavelmente um pouco mais lento.

    
por Oli 25.07.2014 / 11:56