Usando sed para extrair texto entre 2 tags

16

Eu tenho um arquivo .xml e estou tentando fazer uma "instalação de grupo" em uma máquina RHEL6, pois existem várias centenas de bibliotecas nesse arquivo .xml ... (perto de 16 000 linhas).

Portanto, estou tentando extrair os nomes de grupos contidos no arquivo .xml que possui essa estrutura:

<b>
<group>
<id> group name </id>
   <packages>
   ...
   </packages>
<id> group name 2 </id>
   <packages>
   ...
   </packages>
<id> etc... </id>
</group>
</b>

Basicamente, é isso que eu tentei:

sed -n '/<id>/,/<\/id>/p' test1.txt > test2.txt

Copiei o arquivo .xml para test1.txt. Estou tentando extrair os nomes de grupos do test1.txt para um segundo arquivo chamado test2.txt. No entanto, com a linha acima, ele está extraindo tudo, desde a PRIMEIRA <id>tag até a última </id>tag no meu arquivo. Como posso alterar meu código para extraí-lo várias vezes?

Minha segunda pergunta seria: o plugin -downloadonly também funciona com grupos para yum?

Guillaume F.
fonte
3
Oh, querida, analisando XML com regexps novamente. Isso está pedindo problemas ...
gniourf_gniourf
1
Dê uma olhada nisso
alecail
8
Ele não está pedindo para analisar XML, mas para extrair uma correspondência específica de bytes. Há uma diferença fundamental.
Runium

Respostas:

31

Parece que o que você precisa é mais algo do tipo

sed -n 's:.*<id>\(.*\)</id>.*:\1:p'

(assumindo como na sua amostra que <id>e </id>estão na mesma linha e que há apenas um <id>...</id>por linha).

Ou use uma ferramenta compatível com XML:

xmlstarlet sel -t -v '//id' -n
Stéphane Chazelas
fonte
Isso é muito legal, felicidades!
Fduff
2

Por favor, tente com

xml_grep 'id' file.xml --text_only
Kiran Kumar M Reddy
fonte
1
$ echo '<id>I am a sample group</id>' | sed 's/<\/\?[^>]\+>//g'
I am a sample group
$

Isso funcionará com qualquer tag, é claro, também com <a href="...">...</a>âncoras. Nenhum GNUisms usado - o suporte básico a regex sedserá suficiente.
No entanto : observe que as tags de abertura e fechamento devem estar na mesma linha; caso contrário, a declaração precisará ser reescrita novamente.

erro de sintaxe
fonte
1

Este é XML, você deve usar um analisador XML. Aqui está uma solução usando o XMLStarlet :

$ xml sel -t -v '//group/id' -nl data.xml
 group name
 group name 2

A expressão XPath //group/idselecionará qualquer idnó abaixo de um groupnó. Os -t -vmeios "use o seguinte modelo para extrair valores". O -nlfinal garantirá que a saída seja finalizada com uma nova linha.

O exemplo acima usa um arquivo XML que é idêntico ao seu, mas com qualquer linha que contenha ...removida.

Kusalananda
fonte
0

Eu li este post procurando resolver o problema de extrair o Reqd. Pacotes do DVD RHEL 7.3repos.xml , que eu acho que é exatamente o que o autor acima estava tentando fazer. Então, espero que este script possa ajudar outra pessoa ... Eu o usei muitas vezes agora.

Então, eu precisava instalar o grupo "GNOME DESKTOP" no meu servidor RHEL7 "Instalação Mínima" que não tinha X / GUI configurado.

[root@rac01]# yum group list
Loaded plugins: ulninfo
There is no installed groups file.

Hmmmmm… nenhuma lista de grupos no DVD para yum (sim, eu tentei todas as correções usuais do "google" e nunca funcionou), então recorri à fonte da lista do xml.

  1. Monte o DVD.
  2. Encontre o arquivo XML com minha lista de pacotes necessária.
  3. Extraia a lista de grupos de pacotes.
  4. Percorra a lista de pacotes e instale (incluindo dependências).
  5. Supondo que você tenha executado createrepo /your/local_rpms/dir.

    sudo su -
    mkdir /mnt/sr0
    mount /dev/sr0 /mnt/sr0
    cd /mnt/sr0
    
    FILE=$(find . -name "*.xml" | xargs grep '<id>gnome-desktop<\/id>'| cut -d: -f1)
    PKGLIST=$(sed -n '/<id>gnome-desktop<\/id>/,/<\/packagelist>/p' $FILE \
    | sed  -n  '/^ *<packagelist> *$/,/^ *<\/packagelist> *$/{/<packagereq type>/{d};p}' \
    | cut -d'>' -f2 \
    | cut -d'<' -f1)
    
    for p in ${PKGLIST}
       do
        yum deplist ${p}* | awk '/provider:/ {print $2}' | sort -u | xargs yum -y install
    done
    
captaink
fonte