Leer datos de un archivo de entrada y colocar los datos en los campos apropiados en un xml

Leer datos de un archivo de entrada y colocar los datos en los campos apropiados en un xml

Tengo un archivo de entrada y un archivo xml.

fichero de entrada-

/user/sht
227_89,45_99
/user/sht1
230_90
/user/sht2
441_50

El archivo tiene líneas alternativas que contienen ruta y posición.

archivo xml-

<aaa><command name="move">
<domain>
<path></path>
<positions></positions>
</domain>
<domain>
<path></path>
<positions></positions>
</domain>
<domain>
<path></path>
<positions></positions>
</domain>
</command>
</aaa>

Necesito escribir un script para proporcionar el siguiente xml de salida requerido y luego ejecutar algunos comandos usando el siguiente xml como entrada.

<aaa><command name="move">
<domain>
<path>/user/sht</path>
<positions>227_89,45_99</positions>
</domain>
<domain>
<path>/user/sht1</path>
<positions>230_90</positions>
</domain>
<domain>
<path>/user/sht2</path>
<positions>441_50</positions>
</domain>
</command>
</aaa>

Intenté extraer línea por línea del archivo de entrada y colocarlo en el xml, pero el problema es que cada aparición de <path>se reemplaza por la primera línea de entrada.

Usando GNU bash 4.1.2.

Respuesta1

Con un solo sedscript GNU podrías hacer algo como

sed -n '/<aaa>/,/<.aaa>/!{H;d}
G;:a
s_>\(</path>.*\n\)\n\([^\n]*\)_>\2\1_
s_>\(</positions>.*\n\)\n\([^\n]*\)_>\2\1_;
ta;P;s/.*\n\n/\n/;h' input.txt input.xml

La primera línea recopila todas las líneas del primer archivo en el búfer de retención.

Luego, para cada línea del segundo archivo, al búfer de retención se le agrega G. Si es un patho positionsel primer segmento del búfer de retención se mueve dentro de las etiquetas con uno de los dos scomandos.

En cualquier caso, la línea se imprime ( P) y se elimina ( s/.*\n\n/\n/) y lo que queda de la lista de reemplazo se mueve nuevamente al búfer de retención para el siguiente ciclo ( h).

Respuesta2

Script de Shell que cubrirá sus necesidades

#!/bin/bash
count=0          ## counting lines
while read var
do
    occurance=$[$count/2+1];                  ## check nth occurance of search path/position from file
if [ $((count%2)) -eq 0 ];                ## If counting even replace path values else replace position values
then
    perl -pe 's{<path>*}{++$n == '$occurance' ? "<path>'$var'" : $&}ge' xml > xml1
else
    perl -pe 's{<positions>*}{++$n == '$occurance' ? "<positions>'$var'" : $&}ge' xml > xml1
fi
yes|cp xml1 xml
    count=$[$count +1]
done <./input
rm xml1 

Respuesta3

Usando GNU sed y el formato para XML como se muestra:

sed -e '
   /<domain>/,/<\/domain>/!b
   /<\(path\|positions\)><\/\1>/!b
   s//<\1>/
   R input_file
' XML_file |
sed -e '
   /<\(path\|positions\)>.*/N
   s//&\n<\/\1>/
   s/\n//g
'

Resultados

<aaa><command name="move">
<domain>
<path>/user/sht</path>
<positions>227_89,45_99</positions>
</domain>
<domain>
<path>/user/sht1</path>
<positions>230_90</positions>
</domain>
<domain>
<path>/user/sht2</path>
<positions>441_50</positions>
</domain>
</command>
</aaa>

Respuesta4

En cáscara:

echo '<aaa><command name="move">'
echo '<domain>'

while true
do read v || break
   echo "<path>$v</path>"
   read v || break
   echo "<positions>$v</positions>"
done < /path/to/YourInputFile

echo '</domain>
</command>
</aaa>'

información relacionada