Używanie sed do wyodrębnienia tekstu między 2 znacznikami

16

Mam plik .xml i próbuję wykonać „instalację grupową” na komputerze RHEL6, ponieważ plik ten zawiera kilkaset bibliotek ... (blisko 16 000 wierszy).

Dlatego próbuję wyodrębnić nazwy grup zawarte w pliku .xml, który ma następującą strukturę:

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

Zasadniczo to właśnie próbowałem:

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

Skopiowałem plik .xml do test1.txt. Próbuję wyodrębnić nazwy grup z test1.txt do drugiego pliku o nazwie test2.txt. Jednak z linią powyżej wyodrębnia wszystko od PIERWSZEGO <id>znacznika do ostatniego </id>znacznika w moim pliku. Jak mogę zmienić kod, aby wyodrębnić go kilka razy?

Moje drugie pytanie brzmi: czy wtyczka -downloadonly działa również z grupami dla yum?

Guillaume F.
źródło
3
Och, jeszcze raz, parsowanie XML za pomocą wyrażeń regularnych. To prosi o kłopoty ...
gniourf_gniourf
1
Spójrz na to
alecail
8
Nie prosi o parsowanie XML, ale wyodrębnia określone dopasowanie bajtów. Istnieje zasadnicza różnica.
Runium,

Odpowiedzi:

31

Wygląda na to, że potrzebujesz czegoś więcej

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

(zakładając, jak w twojej próbce, że <id>i </id>są na tej samej linii i że jest tylko jedna <id>...</id>na linię).

Lub użyj narzędzia obsługującego XML:

xmlstarlet sel -t -v '//id' -n
Stéphane Chazelas
źródło
To bardzo miłe, na zdrowie!
fduff
2

Spróbuj z

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

Będzie to działać z dowolnym tagiem, oczywiście także z <a href="...">...</a>kotwicami. Nie użyto GNUism - sedwystarczy podstawowa obsługa wyrażeń regularnych .
Należy jednak pamiętać, że zarówno otwierające, jak i zamykające tagi muszą znajdować się w tym samym wierszu, w przeciwnym razie instrukcja musiałaby zostać przepisana ponownie.

błąd składni
źródło
1

To jest XML, powinieneś użyć parsera XML. Oto rozwiązanie wykorzystujące XMLStarlet :

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

Wyrażenie XPath //group/idwybierze dowolny idwęzeł poniżej groupwęzła. Te -t -vśrodki „użyć następującego szablonu, aby wyodrębnić wartości”. Na -nlkońcu upewni się, że wyjście jest zakończone nową linią.

W powyższym przykładzie użyto pliku XML identycznego z twoim, ale z ...usuniętym wierszem .

Kusalananda
źródło
0

Przeczytałem ten post, szukając rozwiązania problemu wyodrębnienia Reqd. Pakiety z DVD RHEL 7.3 repos.xml, które moim zdaniem są dokładnie tym, co próbował autor powyżej. Mam więc nadzieję, że ten skrypt może pomóc komuś innemu… Używałem go już wiele razy.

Musiałem więc zainstalować grupę „GNOME DESKTOP” na moim serwerze RHEL7 „Minimalna instalacja”, w którym nie skonfigurowano interfejsu X / GUI.

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

Hmmmmm… brak listy grup na DVD dla mniam (tak, próbowałem wszystkich zwykłych poprawek „google” i nigdy nie działało), więc uciekłem się do twardego źródła listy z xml.

  1. Zamontuj dysk DVD.
  2. Znajdź plik XML z moją listą wymaganych pakietów.
  3. Wyodrębnij listę grup pakietów.
  4. Pętlę przez listę pakietów i instalację (w tym zależności).
  5. Zakładając, że uciekłeś 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
    
kapitan
źródło