AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / computer / Perguntas / 1487269
Accepted
Rafael Bankosegger
Rafael Bankosegger
Asked: 2019-09-29 09:21:28 +0800 CST2019-09-29 09:21:28 +0800 CST 2019-09-29 09:21:28 +0800 CST

Usando sed para filtrar itens RSS

  • 772

Eu gostaria de escrever um script que:

  • Toma algum URL de RSS-Feed como entrada
  • Baixe o feed
  • Exclui todas as <item> ...</item>ocorrências em que a titletag não corresponde a alguma expressão regular.

O exemplo a seguir deve ilustrar isso. Digamos que temos um RSS Feed com esses três itens:

  • Projeto Foo - Vamos começar!
  • Algo totalmente diferente
  • Outra atualização sobre o Projeto Foo

Quero manter apenas os itens que têm "Projeto Foo" em seu título.

Exemplo de arquivo de entrada:

<?xml version="1.0" encoding="iso-8859-1"?>
<rss version="2.0">
<channel>
<title>My glorious newsfeed</title>
<description>...</description>
<link>...</link>
<language>...</language>
<pubDate>...</pubDate>

<item>
<title>Project Foo - Let's get started!</title>
<link>...</link>
<description>...</description>
<pubDate>...</pubDate>
</item>

<item>
<title>Something else entirely</title>
<link>...</link>
<description>...</description>
<pubDate>...</pubDate>
</item>

<item>
<title>Another update on Project Foo</title>
<link>...</link>
<description>...</description>
<pubDate>...</pubDate>
</item>

</channel>
</rss>

Exemplo de arquivo de saída:

<?xml version="1.0" encoding="iso-8859-1"?>
<rss version="2.0">
<channel>
<title>My glorious newsfeed</title>
<description>...</description>
<link>...</link>
<language>...</language>
<pubDate>...</pubDate>

<item>
<title>Project Foo - Let's get started!</title>
<link>...</link>
<description>...</description>
<pubDate>...</pubDate>
</item>

<item>
<title>Another update on Project Foo</title>
<link>...</link>
<description>...</description>
<pubDate>...</pubDate>
</item>

</channel>
</rss>

Se possível, gostaria de ficar longe de coisas como pythone fazer isso com ferramentas de linha de comando. Mas eu sou um grande novato usando sedetc. e preciso de ajuda :)

Aqui está o que eu tenho até agora:

cat sample-feed.xml \
  | tr -d '\n' \
  | sed $'s/\<item\>/\\\n\<item\>/g;s/\<\/channel\><\/rss\>/\\\n\<\/channel\><\/rss\>/g' \
  | sed '/^\<item\>/ d'

Primeiro, excluo todas as novas linhas. Em seguida, adiciono novas linhas para trazer cada uma <item>...</item>para sua própria linha. O comando final até agora exclui todas as linhas que começam com <item>. Por

O resultado é um feed rss válido sem nenhum item:

<?xml version="1.0" encoding="iso-8859-1"?><rss version="2.0"><channel><title>My glorious newsfeed</title><description>...</description><link>...</link><language>...</language><pubDate>...</pubDate>    
</channel></rss>

Para fazer isso funcionar com URLs em vez de arquivos locais, eu apenas substituiria cat sample-feed.xmlpor curl -s <some url>.

O que ainda falta é uma modificação no comando sed '/^\<item\>/ d'que exclui apenas as linhas que começam com <item>, mas não contêm "Projeto Foo".

Então, se você pudesse me ajudar a descobrir o que a última linha deveria dizer, eu ficaria muito feliz. Por outro lado, tenho certeza de que existe uma maneira mais elegante de fazer isso. Pelo que vi, sedé bastante poderoso e deve ser possível fazer isso em um sedcomando.

Aguardo suas respostas :-)

sed curl
  • 1 1 respostas
  • 219 Views

1 respostas

  • Voted
  1. Best Answer
    Rafael Bankosegger
    2019-09-30T06:14:44+08:002019-09-30T06:14:44+08:00

    Conforme sugerido nos comentários, tentei usar xmlstarletpara resolver isso e funciona bem. Aqui está o meu roteiro

    xml ed -d '//item[not(contains(title,"Project Foo"))]' < sample_rss.xml
    

    Vamos supor que o conteúdo do feed esteja no arquivo sample_rss.xml. Esse conteúdo é alimentado em xml ed -d, que exclui qualquer nota que corresponda à expressão XPath fornecida. A expressão XPath procura por qualquer um <item> que não tenha um nó <title>que contenha o texto "Project Foo".

    Isso parece funcionar bem e também estou muito feliz com o tempo de execução:

    real    0m0.003s
    user    0m0.001s
    sys     0m0.002s
    

    Cuidado com os namespaces

    Se você quiser fazer isso funcionar com feeds rss ou atom adequados, você pode perceber que feedcontém um atributo XML Namespace ( xmlns), assim como neste exemplo do YouTube:

    <?xml version="1.0" encoding="UTF-8"?>
    <feed xmlns:yt="http://www.youtube.com/xml/schemas/2015" xmlns:media="http://search.yahoo.com/mrss/" xmlns="http://www.w3.org/2005/Atom">
       ...
    </feed>
    

    Então, o script acima não funcionará mais! Isso me causou muita dor de cabeça consertá-lo, mas aqui está como fazê-lo funcionar:

    xml ed -d '//_:entry[not(contains(_:title,"Project Foo"))]' < youtube_rss.xml
    

    Mais sobre este problema de namespace aqui: http://xmlstar.sourceforge.net/doc/UG/ch05.html

    • 1

relate perguntas

  • sed/awk: remove linhas semelhantes após a primeira ocorrência

  • sed: corresponde a uma string entre duas correspondências consecutivas diferentes em todas as ocorrências

  • Diferentes erros de ondulação acontecem ocasionalmente

  • data de correspondência do padrão sed

  • sed-remove todas as ocorrências de um caractere de uma linha, exceto a última

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    O visualizador de fotos do Windows não pode ser executado porque não há memória suficiente?

    • 5 respostas
  • Marko Smith

    Como faço para ativar o WindowsXP agora que o suporte acabou?

    • 6 respostas
  • Marko Smith

    Área de trabalho remota congelando intermitentemente

    • 7 respostas
  • Marko Smith

    Serviço do Windows 10 chamado AarSvc_70f961. O que é e como posso desativá-lo?

    • 2 respostas
  • Marko Smith

    O que significa ter uma máscara de sub-rede /32?

    • 6 respostas
  • Marko Smith

    Ponteiro do mouse movendo-se nas teclas de seta pressionadas no Windows?

    • 1 respostas
  • Marko Smith

    O VirtualBox falha ao iniciar com VERR_NEM_VM_CREATE_FAILED

    • 8 respostas
  • Marko Smith

    Os aplicativos não aparecem nas configurações de privacidade da câmera e do microfone no MacBook

    • 5 respostas
  • Marko Smith

    ssl.SSLCertVerificationError: falha na verificação do certificado [SSL: CERTIFICATE_VERIFY_FAILED]: não foi possível obter o certificado do emissor local (_ssl.c:1056)

    • 4 respostas
  • Marko Smith

    Como posso saber em qual unidade o Windows está instalado?

    • 6 respostas
  • Martin Hope
    Albin Como faço para ativar o WindowsXP agora que o suporte acabou? 2019-11-18 03:50:17 +0800 CST
  • Martin Hope
    fixer1234 O "HTTPS Everywhere" ainda é relevante? 2019-10-27 18:06:25 +0800 CST
  • Martin Hope
    Kagaratsch O Windows 10 exclui muitos arquivos minúsculos muito lentamente. Algo pode ser feito para agilizar? 2019-09-23 06:05:43 +0800 CST
  • Martin Hope
    andre_ss6 Área de trabalho remota congelando intermitentemente 2019-09-11 12:56:40 +0800 CST
  • Martin Hope
    Riley Carney Por que colocar um ponto após o URL remove as informações de login? 2019-08-06 10:59:24 +0800 CST
  • Martin Hope
    zdimension Ponteiro do mouse movendo-se nas teclas de seta pressionadas no Windows? 2019-08-04 06:39:57 +0800 CST
  • Martin Hope
    Inter Sys Como Ctrl+C e Ctrl+V funcionam? 2019-05-15 02:51:21 +0800 CST
  • Martin Hope
    jonsca Todos os meus complementos do Firefox foram desativados repentinamente, como posso reativá-los? 2019-05-04 17:58:52 +0800 CST
  • Martin Hope
    MCK É possível criar um código QR usando texto? 2019-04-02 06:32:14 +0800 CST
  • Martin Hope
    SoniEx2 Altere o nome da ramificação padrão do git init 2019-04-01 06:16:56 +0800 CST

Hot tag

windows-10 linux windows microsoft-excel networking ubuntu worksheet-function bash command-line hard-drive

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve