Usando sed per estrarre il testo tra 2 tag


16

Ho un file .xml e sto provando a fare una "installazione di gruppo" su una macchina RHEL6 poiché ci sono diverse centinaia di librerie in quel file .xml ... (vicino a 16000 righe).

Sto quindi cercando di estrarre i nomi dei gruppi contenuti nel file .xml che ha questa struttura:

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

Fondamentalmente, questo è quello che ho provato:

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

Ho copiato il file .xml in test1.txt. Sto cercando di estrarre i nomi dei gruppi da test1.txt in un secondo file chiamato test2.txt. Tuttavia, con la riga sopra, sta estraendo tutto dal PRIMO <id>tag all'ultimo </id>tag nel mio file. Come posso modificare il mio codice per estrarlo più volte?

La mia seconda domanda sarebbe: il plugin -downloadonly funziona anche con i gruppi per yum?


3
Oh caro, analizzando di nuovo XML con regexps. Chiede problemi ...
gniourf_gniourf,

1
Dai

8
Non sta chiedendo di analizzare XML, ma di estrarre una specifica corrispondenza di byte. C'è una differenza fondamentale.
Runium,

Risposte:


31

Sembra che ciò di cui hai bisogno sia più qualcosa sulla falsariga di

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

(supponendo come nel tuo esempio che <id>e </id>siano sulla stessa riga e che ce ne sia solo uno <id>...</id>per riga).

Oppure utilizza uno strumento compatibile con XML:

xmlstarlet sel -t -v '//id' -n

È molto pulito, evviva!
fduff,


1
$ echo '<id>I am a sample group</id>' | sed 's/<\/\?[^>]\+>//g'
I am a sample group
$

Funzionerà con qualsiasi tag, ovviamente anche con <a href="...">...</a>ancore. Nessun GNU utilizzato - sedbasterà il supporto regex di base .
Tuttavia : si noti che sia i tag di apertura che quelli di chiusura devono trovarsi nella stessa riga, altrimenti la dichiarazione dovrebbe essere riscritta di nuovo.


1

Questo è XML, dovresti usare un parser XML. Ecco una soluzione che utilizza XMLStarlet :

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

L'espressione XPath //group/idselezionerà qualsiasi idnodo sotto agroup nodo. Il -t -vmezzo "usa il modello seguente per estrarre i valori". Alla -nlfine si assicurerà che l'output sia terminato con una nuova riga.

L'esempio precedente utilizza un file XML identico al tuo, ma con qualsiasi riga contenente ...rimossa.


0

Ho letto questo post cercando di risolvere il problema dell'estrazione di Reqd. Pacchetti dal DVD RHEL 7.3repos.xml , che penso sia esattamente ciò che l'autore sopra stava cercando di fare. Quindi spero che questo script possa aiutare qualcun altro ... l'ho usato molte volte ora.

Quindi avevo bisogno di installare il gruppo "GNOME DESKTOP" sul mio server RHEL7 "Installazione minima" che non aveva X / GUI configurato.

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

Hmmmmm ... nessun elenco di gruppi sul DVD per yum (sì, ho provato tutte le solite correzioni "google" e non ho mai funzionato) quindi ho fatto ricorso all'elenco hard da xml.

  1. Montare il DVD.
  2. Trova il file XML con il mio elenco di pacchetti richiesto.
  3. Estrarre l'elenco di gruppi di pacchetti.
  4. Scorri l'elenco dei pacchetti e installa (incl. Dipendenze).
  5. Supponendo che tu abbia corso 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
    
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.