Verwenden von sed zum Extrahieren von Text zwischen zwei Tags

16

Ich habe eine .xml-Datei und versuche, eine "Gruppeninstallation" auf einem RHEL6-Computer durchzuführen, da diese .xml-Datei mehrere hundert Bibliotheken enthält ... (fast 16.000 Zeilen).

Ich versuche daher, die Gruppennamen zu extrahieren, die in der XML-Datei enthalten sind, die diese Struktur aufweist:

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

Grundsätzlich habe ich Folgendes versucht:

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

Ich habe die XML-Datei in die Datei test1.txt kopiert. Ich versuche, die Gruppennamen aus der Datei test1.txt in eine zweite Datei mit dem Namen test2.txt zu extrahieren. Mit der obigen Zeile wird jedoch alles vom ERSTEN <id>Tag bis zum letzten </id>Tag in meiner Datei extrahiert . Wie kann ich meinen Code ändern, um ihn mehrmals zu extrahieren?

Meine zweite Frage wäre: Funktioniert das -downloadonly-Plugin auch mit Gruppen für yum?

Guillaume F.
quelle
3
Oh je, ich analysiere XML wieder mit regulären Ausdrücken. Das bittet um Ärger ...
gniourf_gniourf
1
Werfen Sie einen Blick auf diese
alecail
8
Er bittet nicht, XML zu analysieren , sondern eine bestimmte Übereinstimmung von Bytes zu extrahieren. Es gibt einen grundsätzlichen Unterschied.
Runium

Antworten:

30

Klingt so, als ob Sie eher etwas im Sinne von brauchen

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

(Angenommen, wie in Ihrem Beispiel, dass sich die <id>und </id>in derselben Zeile befinden und es nur eine <id>...</id>pro Zeile gibt).

Oder verwenden Sie ein XML-fähiges Tool:

xmlstarlet sel -t -v '//id' -n
Stéphane Chazelas
quelle
Das ist sehr ordentlich, Prost!
Fduff
2

Bitte versuchen Sie es mit

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

Dies funktioniert mit jedem Tag, natürlich auch mit <a href="...">...</a>Ankern. Keine GNUisms verwendet - grundlegende Regex-Unterstützung sedwird ausreichen.
Allerdings : Bitte beachten Sie , dass sowohl das Öffnen und Schließen - Tags müssen in der gleichen Zeile sein, da sonst die Aussage wieder werden müßte neu geschrieben.

Syntax-Fehler
quelle
1

Dies ist XML. Sie sollten einen XML-Parser verwenden. Hier ist eine Lösung mit XMLStarlet :

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

Der XPath-Ausdruck //group/idwählt einen beliebigen idKnoten unter einem groupKnoten aus. Das -t -vbedeutet "Verwenden Sie die folgende Vorlage, um Werte zu extrahieren". Das -nlam Ende sorgt dafür, dass die Ausgabe mit einem Zeilenumbruch beendet wird.

Im obigen Beispiel wird eine XML-Datei verwendet, die mit Ihrer identisch ist, die jedoch keine Zeile enthält ....

Kusalananda
quelle
0

Ich habe diesen Beitrag gelesen, um das Problem des Extrahierens von Reqd zu lösen. Pakete von der RHEL 7.3 DVD repos.xml, die genau das ist, was der Autor oben versucht hat. Ich hoffe, dass dieses Skript jemand anderem hilft. Ich habe es jetzt schon oft benutzt.

Daher musste ich die Gruppe "GNOME DESKTOP" auf meinem RHEL7-Server "Minimal Install" installieren, auf dem keine X / GUI konfiguriert war.

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

Hmmmmm ... keine Gruppenliste auf der DVD für yum (yep, ich habe alle üblichen "google" -Fixes ausprobiert und es hat nie funktioniert), also habe ich auf die harte Quelle der Liste von xml zurückgegriffen.

  1. Hängen Sie die DVD ein.
  2. Suchen Sie die XML-Datei mit meiner erforderlichen Paketliste.
  3. Extrahieren Sie die Liste der Paketgruppen.
  4. Durchlaufen Sie die Paketliste und installieren Sie (inkl. Abhängigkeiten).
  5. Vorausgesetzt, Sie sind gelaufen 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
    
Kapitän
quelle