Tengo un archivo XML grande que tiene un tamaño aproximado de 2 GB. Para hacer las cosas interesantes, todos los datos están en una sola línea.
Estoy tratando de insertar un carácter de nueva línea al final de etiquetas específicas en este archivo para convertirlo en un archivo de varias líneas que me permitirá dividirlo y hacer más con él.
root@server:~# sed -i -e 's/\<\/Dummy\>/\<\/Dummy\>\\\n/g' file_nameProbé sed, vi y joe sin suerte. La longitud de cada nodo en el XML es diferente, por lo que no puedo dividir el archivo según la cantidad de caracteres.
¿Hay alguna manera de convertir este gran archivo de una sola línea en un archivo de varias líneas a través de la línea de comandos?
Lo que puede hacer es formatear eso en xml canónico con xmllint xmllint --format pathtofile.xml y luego canalizarlo a sed.
Creo que en realidad haría esto con gawk en lugar de sed.
No ha incluido datos de entrada, así que inventaré algunos.
$ printf '<a><b></b><b></b></a><a><c></c></a>' | gawk -vRS='</a>' '{print $0 RS}' <a><b></b><b></b></a> <a><c></c></a>Normalmente, awk (o gawk) considerará cada línea como un registro único, con cada línea dividida en campos delimitados por espacios en blanco.
Si, en cambio, divide los registros por alguna etiqueta XML, puede confiar en el hecho de que print agregará una nueva línea como el ORS predeterminado (separador de registro de salida) después de imprimir cada "registro de entrada".
A diferencia de una solución sed que intentará leer un "registro" (línea) completo en la memoria para realizar acciones en él, sospecho que esta solución recorrería su archivo solo usando suficiente memoria para "recordar" el espacio entre los separadores de registro . (Esto aborda la preocupación del "archivo grande").
Otras tres cosas a tener en cuenta.
Primero, un separador de registros NO es un concepto nativo de XML, por lo que cualquier solución que use sed, awk o cualquier otra cosa que no interprete XML de forma nativa es un truco . Siempre obtendrá mejores resultados utilizando herramientas que admitan de forma nativa su formato de datos.
En segundo lugar, dado que en mi ejemplo especifiqué un separador de registros que es el cierre de una etiqueta XML, se podría pensar que los datos de entrada tienen TRES REGISTROS, el tercero de los cuales es nulo. Si tiene una nueva línea después de su "separador de registro" final, ese tercer registro puede terminar con otro RS en su salida. Ten cuidado. Este es el resultado de la cosa #1.
En tercer lugar, esta es una solución gawk , no una solución awk , porque otras implementaciones de awk generalmente no admiten varios caracteres como separadores de registros.
YMMV. Esta no es una gran solución, pero puede ser suficiente para sus necesidades.
Estoy robando descaradamente mi entrada de la respuesta de ghoti :
$ cat file_name <a><b></b><b></b></a><a><c></c></a>Hay algunas cosas mal con su intento, modificado a una etiqueta más corta aquí:
sed -i -e 's/\<\/a\>/\<\/a\>\\\n/g' file_name No es necesario usar -e en este caso:
sed -i 's/\<\/a\>/\<\/a\>\\\n/g' file_name Para evitar tener que escapar / , podemos usar un delimitador diferente:
sed -i -e 's|\</a\>|\</a\>\\\n|g' file_name Si escapas < > con \< \> , sed 1 cree que te refieres a "límites de palabras", pero en este caso, te refieres al literal < > y no deberías escapar de ellos:
sed -i -e 's|</a>|</a>\\\n|g' file_nameEsto ya hace algo :
$ sed -i -e 's|</a>|</a>\\\n|g' file_name <a><b></b><b></b></a>\ <a><c></c></a>\ [empty line here] Entonces, si realmente quería el \ al final de cada línea, ya casi llegamos. (Si no, puede reemplazar \\\n por \n ).
Cosméticos: no es necesario escribir todo lo que hemos emparejado en la sustitución, solo podemos usar & :
sed -i -e 's|</a>|&\\\n|g' file_name Y finalmente, si nuestro archivo termina con <a> (lo que hace la entrada de ejemplo), es posible que deseemos eliminar la barra invertida (¡y la nueva línea!) del final de nuestra salida:
$ sed -e 's|</a>|&\\\n|g;s/\\\n$//' file_name <a><b></b><b></b></a>\ <a><c></c></a>Por supuesto, todo lo dicho sobre la manipulación de XML con herramientas que no son XML aún se aplica: no debe hacerlo, y si lo hace, espere que su solución se rompa fácilmente.
1 Al menos GNU sed lo hace, pero esto está etiquetado como "Linux" y asumo que está usando GNU sed.