Використання sed для вилучення тексту між 2 тегами


16

У мене є .xml файл, і я намагаюся зробити "групову встановлення" на машині RHEL6, оскільки в цьому .xml-файлі є кілька сотень бібліотек ... (близько 16 000 рядків).

Тому я намагаюся витягти назви груп, що містяться у файлі .xml, який має цю структуру:

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

В основному, це те, що я спробував:

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

Я скопіював .xml файл в test1.txt. Я намагаюся витягти назви груп з test1.txt до другого файлу під назвою test2.txt. Однак у верхньому рядку він витягує все з <id>тегу ПЕРШИЙ до останнього </id>тегу в моєму файлі. Як я можу змінити код, щоб витягнути його кілька разів?

Друге моє запитання було б: чи працює плагін -downloadonly також з групами для yum?


3
О, шановний, знову розбираємо XML з регулярними виразами. Це прохання про неприємності ...
gniourf_gniourf

1
Подивіться на це
alecail

8
Він не просить проаналізувати XML, а витягти конкретну відповідність байтів. Існує принципова різниця.
Руніум

Відповіді:


31

Звучить, що те, що тобі потрібно, - це щось щось більше

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

(Припускаючи , що , як і у вашій вибірці , що <id>і </id>на тій же лінії, що є тільки одна в <id>...</id>кожному рядку).

Або скористайтеся інструментом, знаючим XML:

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

Це дуже акуратно, ура!
fduff


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

Це буде працювати з будь-яким тегом, звичайно, також з <a href="...">...</a>якорями. Ніяких GNUisms не використовується - базової підтримки регулярних виразів sedбуде достатньо.
Однак : зауважте, що і теги для відкриття, і для закриття повинні знаходитися в одному рядку, інакше заяву доведеться переписати знову.


1

Це XML, ви повинні використовувати XML-аналізатор. Ось рішення за допомогою XMLStarlet :

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

Вираз XPath //group/idвибере будь-який idвузол під groupвузлом. В -t -vозначає «використовувати наступний шаблон для вилучення значень». В -nlкінці переконайтеся, що вихід закінчується новим рядком.

У наведеному вище прикладі використовується XML-файл, ідентичний вашому, але з будь-яким рядком, що містить ...видалений.


0

Я прочитав цю публікацію, шукаючи, щоб вирішити проблему вилучення Reqd. Пакети від DVD RHEL 7.3repos.xml , що, на мою думку, саме те, що намагався зробити автор вище. Тож сподіваюся, що цей сценарій може допомогти комусь іншому ... Я його вже багато разів використовував.

Тому мені потрібно було встановити групу "GNOME DESKTOP" на мій сервер RHEL7 "Мінімальна установка", на якому не було налаштовано X / GUI.

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

Хммммм ... немає жодного списку груп на DVD для yum (так, я спробував все звичайне "google" виправити-це і ніколи не працювало), тому вдався до жорсткого джерела списку з XML.

  1. Встановіть DVD.
  2. Знайдіть XML-файл із необхідним списком пакунків.
  3. Витягніть список групи пакунків.
  4. Перегляньте список пакунків та встановіть його (включаючи залежності).
  5. Якщо припустити, що ви бігли 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
    
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.