Luta com grep, sed, awk para filtrar html

1

Estou tentando aprender como usar ferramentas do Linux em uma instalação do cygwin. Eu decidi fazer um projeto para tentar me ensinar os fundamentos do script de shell e, simultaneamente, realizar alguma educação pessoal. Meu projeto original era salvar as páginas html de cada vencedor do Prêmio Sakharov em uma pasta, e escrever um script que processaria todos os arquivos de texto html e retornaria o nome, ano, nascimento e morte em formato hifenizado e país de origem. Devido a certas inconsistências na formatação da data (18 de julho de 1918 x 23 de janeiro de 1938), bem como a incapacidade de lidar com pessoas mortas vs pessoas vivas sem data de falecimento ou descobrir como dizer a um computador como reconhecer nomes de países sem listar manualmente todos os países, eu basicamente desisti deste projeto.

Agora, estou apenas tentando retornar o ano, o nome e o país de origem de cada destinatário da tabela html retirada do Prémio Sakharov página da Wikipédia.

Então, dada a seguinte amostra de html:

<tr>
<td>1988</td>
<td><span style="display:none;">Mandela, Nelson</span><span class="vcard"><span class="fn"><a href="/wiki/Nelson_Mandela" title="Nelson Mandela">Nelson Mandela</a></span></span></td>
<td><a href="/wiki/South_Africa" title="South Africa">South Africa</a></td>
<td>Anti-apartheid activist and later President of South Africa</td>
<td><sup id="cite_ref-twentyyears_5-0" class="reference"><a href="#cite_note-twentyyears-5"><span>[</span>5<span>]</span></a></sup></td>
</tr>
<tr>
<td>1988</td>
<td><span style="display:none;">Marchenko, Anatoly</span><span class="vcard"><span class="fn"><a href="/wiki/Anatoly_Marchenko" title="Anatoly Marchenko">Anatoly Marchenko</a></span></span> (posthumously)</td>
<td><a href="/wiki/Soviet_Union" title="Soviet Union">Soviet Union</a></td>
<td>Soviet dissident, author and humans rights activist</td>
<td><sup id="cite_ref-twentyyears_5-1" class="reference"><a href="#cite_note-twentyyears-5"><span>[</span>5<span>]</span></a></sup></td>
</tr>

qual é a melhor maneira de retornar apenas o ano, o nome e o país de origem de cada destinatário? No momento, estou pensando em apenas escrever um script awk que retorne tudo o que não corresponde a / lt; * > /, mas isso não é exatamente o que eu quero. Alguém pode me dar algumas dicas ou idéias de como escolher os nomes, ano e países especificamente? Ou pelo menos alguns livros com problemas de amostra melhores e mais gerenciáveis do que os que eu poderia criar? Nada disso soou irracional quando eu comecei ...

    
por tzisc 20.03.2013 / 05:42

3 respostas

3

Como foi mencionado regex não é bom para analisar html . Semelhante a outra resposta de análise , você pode criar um verso em Ruby como o seguinte para fazer isso por você. Note que é necessário Nokogiri que você pode instalar como gem ( sudo gem install nokogiri ).

ruby -rnokogiri -e 'Nokogiri::HTML(readlines.join).css("tr").each { |tr| tr.xpath(".//td").take(3).each { |td| puts td.content } }' sample.html

Ele lê o arquivo fornecido, neste caso, sample.html, obtém todos os elementos tr e, para cada elemento, imprime o conteúdo dos três primeiros elementos td .

Para sua amostra, será exibida:

1988
Mandela, NelsonNelson Mandela
South Africa
1988
Marchenko, AnatolyAnatoly Marchenko (posthumously)
Soviet Union

O problema são as linhas que contêm os nomes duas vezes, por ex. (formatado para ser mais fácil de ler)

<td>
  <span style="display:none;">Mandela, Nelson</span>
  <span class="vcard"><span class="fn">
      <a href="/wiki/Nelson_Mandela" title="Nelson Mandela">Nelson Mandela</a>
    </span>
  </span>
</td>

em que o nome é o primeiro em span com style="display:none;" e depois novamente em outro span . Não sei como extrair apenas o nome que não está dentro de um elemento com style="display:none; . (Encontrei o link e link , mas eles não descrevem a técnica certa. Talvez alguém consiga criar uma correção por meio do link ?)

    
por 20.03.2013 / 09:42
0

Eu criei o pacote node.js, que pode ser usado aqui: gumba . É uma espécie de awk, substituição de sed.

então, no seu exemplo, funcionará assim:

cat file.html | gumba "stripTags()"

quais saídas:

1988
Mandela, NelsonNelson Mandela
South Africa
Anti-apartheid activist and later President of South Africa
[5]


1988
Marchenko, AnatolyAnatoly Marchenko (posthumously)
Soviet Union
Soviet dissident, author and humans rights activist
[5]

Embora aqui eu ache melhor não usar oneliners, mas escrever scripts em qualquer idioma que você conheça.

    
por 11.04.2013 / 17:19
0
sed -rn '
    /<tr>/ {
        n
        s#<td>([^<]*)</td>##
        h
        n
        s#<td><span[^>]*>([^<]*)</span>.*##
        H
        n
        s#<td><a href=[^>]*>([^<]*)</a>.*##
        H
        x;p
    }
' file

1988
Mandela, Nelson
South Africa
1988
Marchenko, Anatoly
Soviet Union
    
por 24.01.2017 / 23:16

Tags