Usando sed para extraer texto entre 2 etiquetas


16

Tengo un archivo .xml y estoy tratando de hacer una "instalación grupal" en una máquina RHEL6, ya que hay varios cientos de bibliotecas en ese archivo .xml ... (cerca de 16 000 líneas).

Por lo tanto, estoy tratando de extraer los nombres de grupo contenidos en el archivo .xml que tiene esta estructura:

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

Básicamente, esto es lo que he intentado:

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

Copié el archivo .xml a test1.txt. Estoy tratando de extraer los nombres de grupo de test1.txt a un segundo archivo llamado test2.txt. Sin embargo, con la línea anterior, está extrayendo todo, desde la PRIMERA <id>etiqueta hasta la última </id>etiqueta en mi archivo. ¿Cómo puedo cambiar mi código para extraerlo varias veces?

Mi segunda pregunta sería: ¿el complemento -downloadonly funciona tan bien con grupos para yum?


3
Oh querido, analizando XML con expresiones regulares de nuevo. Eso es pedir problemas ...
gniourf_gniourf

1
Echa un vistazo a esto
alecail

8
No está pidiendo analizar XML, sino extraer una coincidencia específica de bytes. Hay una diferencia fundamental.
Runium

Respuestas:


31

Parece que lo que necesitas es más algo en la línea de

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

(suponiendo, como en su muestra, que <id>y </id>están en la misma línea y que solo hay uno <id>...</id>por línea).

O use una herramienta compatible con XML:

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

Eso es muy bueno, ¡salud!
fduff


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

Esto funcionará con cualquier etiqueta, por supuesto también con <a href="...">...</a>anclajes. No se utilizan GNUisms: el soporte básico de expresiones regulares sedserá suficiente.
Sin embargo : tenga en cuenta que las etiquetas de apertura y cierre deben estar en la misma línea, de lo contrario, la declaración tendría que reescribirse nuevamente.


1

Esto es XML, debe usar un analizador XML. Aquí hay una solución usando XMLStarlet :

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

La expresión XPath //group/idseleccionará cualquier idnodo debajo de un groupnodo. Los -t -vmedios "usan la siguiente plantilla para extraer valores". Al -nlfinal se asegurará de que la salida finalice con una nueva línea.

El ejemplo anterior usa un archivo XML que es idéntico al suyo, pero con cualquier línea que contenga ...eliminada.


0

Leí esta publicación buscando resolver el problema de extraer Reqd. Paquetes del DVD RHEL 7.3 repos.xml, que creo que es exactamente lo que el autor anterior estaba tratando de hacer. Así que espero que este script pueda ayudar a alguien más ... Lo he usado muchas veces ahora.

Así que necesitaba instalar el grupo "GNOME DESKTOP" en mi servidor RHEL7 "Minimal Install" que no tenía X / GUI configurado.

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

Hmmmmm ... no hay una lista de grupos en el DVD para yum (sí, probé todos los arreglos habituales de "google" y nunca funcionó), así que recurrí a la lista de fuente dura de xml.

  1. Monta el DVD.
  2. Encuentre el archivo XML con mi lista de paquetes requerida.
  3. Extraiga la lista de grupo de paquetes.
  4. Recorra la lista de paquetes e instálela (incluidas las dependencias).
  5. Asumiendo que has corrido 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
    
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.