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 sed
script 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 path
o positions
el primer segmento del búfer de retención se mueve dentro de las etiquetas con uno de los dos s
comandos.
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>'