Dividir el archivo según la etiqueta XML inicial y final

Dividir el archivo según la etiqueta XML inicial y final

¿Se puede utilizar la división para dividir un archivo en varios segmentos donde el tamaño de cada segmento se basa en el número de coincidencias de un elemento XML?

Por ejemplo, para la siguiente división XML cuando se encuentra "<test xsi:type="update" locale="en_US">"es 2

<?xml version="1.0" encoding="UTF-8"?>
<testers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<test xsi:type="update" locale="en_US">
<rval>1</rval>
</test>
<test xsi:type="update" locale="en_US">
<rval>1</rval>
</test>
<test xsi:type="update" locale="en_US">
<rval>1</rval>
</test>
</testers>

Dividir el archivo XML anterior debería generar 2 archivos.

archivo1:

<test xsi:type="update" locale="en_US">
<rval>1</rval>
</test>
<test xsi:type="update" locale="en_US">
<rval>1</rval>
</test>

y el archivo 2 contiene solo una entrada:

<test xsi:type="update" locale="en_US">
<rval>1</rval>
</test>

Esto es lo que estoy intentando:

split -p "<test xsi:type=\"update\" locale=\"en_US\">" test.xml segment

que genera 4 archivos:

segmentaa:

<?xml version="1.0" encoding="UTF-8"?>
<testers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

segmentab :

<test xsi:type="update" locale="en_US">
<rval>1</rval>
</test>

segmentac :

<test xsi:type="update" locale="en_US">
<rval>1</rval>
</test>

segmentado:

<test xsi:type="update" locale="en_US">
<rval>1</rval>
</test>
</testers>

Se puede splitutilizar de la forma que sugiero. El archivo que estoy procesando tiene 40 GB. Utilizo el ejemplo anterior para ilustrar el problema que intento resolver.

Respuesta1

No creo que sea posible con split. Podrías usar awk:

awk '
  BEGIN{ 
    fmt="segment%02d"               # 2 digits for suffix, zero padded
    start="<test xsi:type=\"update\" locale=\"en_US\">"
    end="</test>"
  }
  $0 == start, $0 == end{
    if ($0 == start && ++cnt%2==1){ # for every 2nd start element...
      fname=sprintf(fmt, fcnt++)    # update output filename
    }
    print $0 > fname                # print line, redirect output to fname
  }
' test.xml

Esto produce dos archivos segment00y segment01:

$ head segment*
==> segment00 <==
<test xsi:type="update" locale="en_US">
<rval>1</rval>
</test>
<test xsi:type="update" locale="en_US">
<rval>1</rval>
</test>

==> segment01 <==
<test xsi:type="update" locale="en_US">
<rval>1</rval>
</test>

información relacionada