Tengo archivos que fueron generados por un programa que no puso nuevas líneas al final de los registros. Quiero poner nuevas líneas entre los registros, y puedo hacerlo con un simple script sed:
sed -e 's/}{/}\n{/g'
El problema es que los archivos de entrada tienen un tamaño de varios gigabytes y, por lo tanto, las líneas de entrada a sed tienen varios GB de longitud. sed intenta mantener una línea en la memoria, lo que no funciona en este caso. Probé la --unbuffered
opción, pero eso pareció hacerlo más lento y no permitió que terminara correctamente.
tr
para traducir}
en\n
y luego usarsed
para agregar una}
al final de cada línea? Así:tr '}' '\n' < your_file.txt| sed 's/$/}/'
printf "\n" >> file
}{
repetidos hasta que sea suficiente con varios gigabytes.dd if=file cbs=80 conv=unblock
lo haría, pero rara vez es así de simple.Respuestas:
Puede usar otra herramienta que le permita configurar el separador de registro de entrada. Por ejemplo
Perl
La variable especial
$/
es el separador de registro de entrada. Establecerlo en}{
define líneas como terminando en}{
. De esa manera, puede lograr lo que desea sin leer todo en la memoria.mawk o gawk
Esta es la misma idea.
RS="}{"
establece el separador de registros}{
y luego imprime}
, una nueva línea{
(excepto el primer registro) y el registro actual.fuente
Perl al rescate:
La configuración
$/
de\1024
leerá el archivo en fragmentos de 1024 bytes. La$closing
variable maneja el caso cuando termina un fragmento}
y comienza el siguiente{
.fuente
Deberías hacer:
Es probablemente la solución más eficiente.
Eso pone
{}
a proteger cualquier posible dato final. Con untr
proceso más , puede intercambiarlo y hacer una línea en blanco en la cabecera del primer{
campo. Me gusta...Entonces, el primero, con los datos de ejemplo de don, hace:
... y el segundo sí ...
No hay una nueva línea final para el segundo ejemplo, aunque hay una para el primero.
fuente
Una
sed
utilidad binaria llamadabbe
Me resulta más fácil permanecer con sintaxis de tipo sed en este caso.
Yo mucho prefiero usar la
bbe
utilidad (disponible a través de su uni {,} Linu instalación del paquete de x, eqapt-get
). O aquí, si eres uno de los git, aunque personalmente no he investigado ese enlace en particular.1. Apoya el
s/before/after/
idiomaEs un "Editor de bloques binarios", que admite operaciones de tipo sed (entre otras). Esto incluye el
s/before/after/
idioma de sustitución súper común que necesitas. Tenga en cuenta que, dado que no hay líneas per se desdebbe
el punto de vista, no hay una "g global" al final del comando.Como prueba rápida (tenga en cuenta lo requerido
-e
):produce:
2. En el caso específico de
}{
que}\n{
la conversiónAsí que si tuviéramos un archivo masivo lleno de un millón de números en (por ejemplo) el formato
{1}{2}{3}
...{1000000}
sin retornos de carro, podríamos cambiar el}{
con}\n{
facilidad, y tienen todos los números uno por línea.Esto sería con este
bbe
comando:Como se probó en este bucle zsh, que tomamos solo la cola de:
Lo que produciría esto:
(sin un retorno de carro posterior, por supuesto).
fuente