Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

175
Views
Busque y reemplace en un archivo grande de una sola línea (~ 2 GB) en Linux

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_name

Probé 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?

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

Lo que puede hacer es formatear eso en xml canónico con xmllint xmllint --format pathtofile.xml y luego canalizarlo a sed.

over 4 years ago · Santiago Trujillo Report

0

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.

over 4 years ago · Santiago Trujillo Report

0

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_name

    Esto 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.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!