Использование 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>тега в моем файле. Как я могу изменить свой код, чтобы извлечь его несколько раз?

Мой второй вопрос: плагин -downloadon работает также с группами для yum?

Гийом Ф.
источник
3
О, дорогой, снова разбираю XML с помощью регулярных выражений. Это
напрашивается
1
Посмотрите на это
alecail
8
Он не просит разбирать XML, но извлечь конкретное совпадение байтов. Есть принципиальная разница.
Runium

Ответы:

31

Похоже, что вам нужно больше что-то вроде

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

(Предположим, как в вашем примере, что <id>и </id>находятся в одной строке, и что в <id>...</id>каждой есть только один ).

Или используйте инструмент с поддержкой XML:

xmlstarlet sel -t -v '//id' -n
Стефан Шазелас
источник
Это очень аккуратно, ура!
fduff
2

Пожалуйста, попробуйте с

xml_grep 'id' file.xml --text_only
Киран Кумар Редди М
источник
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.3 repos.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
    
captaink
источник