• Publicidad

Modificar líneas de un archivo directamente

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Modificar líneas de un archivo directamente

Notapor creating021 » 2006-04-16 10:57 @498

Hola a todos.
Miren, tengo un archivo de 200 o más líneas y quiero modificar sólo la número 153 sin usar arrays para el cometido y sin reescribir el archivo por completo.
También sería bueno agregar una línea en un lugar del texto.
¿Como hago esto?
¿Hay algún modulo?
Gracias.
Expect the worst, is it the least you can do?
Avatar de Usuario
creating021
Perlero frecuente
Perlero frecuente
 
Mensajes: 595
Registrado: 2006-02-23 16:17 @720
Ubicación: Frente al monitor

Publicidad

Re: Modificar líneas de un archivo directamente

Notapor explorer » 2006-04-16 11:46 @531

Sí que hay módulos, como File::Alter y Text::Buffer.

Otra forma es leer el fichero línea por línea y cuando se llegue a la que nos interesa ($.), cambiarla. Al final, grabar el resultado (el nuevo fichero cambiado).

Se podría intentar usar el seek para posicionarnos dentro del fichero, pero tendríamos muchos problemas para ajustar la posición de las siguientes líneas (un fichero de texto no es una base de datos con registros de igual tamaño).

Como no quieres usar arrays, tampoco te vale usar Tie::File o el monstruoso IO::All, pero te incluyo las referencias por si te sirven.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor kidd » 2006-04-16 11:50 @534

Hola:

En el cookbook de Perl puedes encontrar una solución para lo que necesitas:

Código: Seleccionar todo
open my $FILE, '+<', $archivo or die "No puedo leer $archivo: $!\n";

my $out= '';

while (<$FILE>) {
    #encuentra la línea que quieres editar y editala
    $out .= $_;
}

seek($FILE, 0, 0) or die "No se pudo hacer seek a $archivo: $!\n";
print {$FILE} $out;
truncate($FILE, tell($FILE)) or die "No se pudo truncar $archivo: $!\n";
close $FILE;



Saludos
Uriel Lizama Perl programmer fundador de Perl en Español
Perl Programming Language
Avatar de Usuario
kidd
Creador de Perl en Español
Creador de Perl en Español
 
Mensajes: 1166
Registrado: 2003-10-15 16:52 @744
Ubicación: México

Notapor Perl user » 2006-04-16 19:01 @834

Con un excelente performance para tareas como esa intenta el módulo Tie::File y accesa el archivo como si fuera un array ( y no... nada que ver con meter todo el archivo a un array directamente en memoria ) además que es parte de la biblioteca estándar de Perl.

Best regards,
Marco A. Manzo
[email protected]
http://www.unixmonkeys.com/amnesiac/
Perl Programming Language
Perl user
Maestro honorario
Maestro honorario
 
Mensajes: 271
Registrado: 2004-11-03 21:11 @924

Notapor kidd » 2006-04-16 19:47 @866

Hola:

Usando el módulo Tie::File como te recomienda Perl User, es muy sencillo lograr lo que quieres.

Por ejemplo, editar la línea 153 así como quieres es tan sencillo como:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
use strict;
use Tie::File;


#Archivo que quieres editar
my $archivo = '/ruta/a/tu/archivo.txt';


#Definimos el array que vamos a usar
my @contenido;


#Empieza la magia
tie @contenido, 'Tie::File', $archivo or die "No se logró hacer el tie: $!";


#Cambiamos la línea 153
# Recuerda que como el array tiene un elemento 0
# la línea 153 realmente es el elemento 152
$contenido[152] = 'Nuevo contenido';


#Eso es todo...wow! ¡Magia!
untie @contenido;
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


El módulo hace un cache del archivo para agilizar las cosas, sin embargo tienes la capacidad de modificar la cantidad de memoria que quieres que use el módulo.

Por ejemplo, puedes poner el límite de memoria a 0, evitando de esta manera que se haga un cache del archivo, por lo que el módulo lee directamente del disco:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
tie @contenido, 'Tie::File', $archivo, memory => 0 or die "No se logró hacer el tie: $!";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Lógicamente entre más capacidad de cache tengas, más rápido se va a realizar el trabajo.

Saludos
Uriel Lizama Perl programmer fundador de Perl en Español
Perl Programming Language
Avatar de Usuario
kidd
Creador de Perl en Español
Creador de Perl en Español
 
Mensajes: 1166
Registrado: 2003-10-15 16:52 @744
Ubicación: México

Notapor creating021 » 2006-04-18 16:07 @713

Muchas gracias a todos por las respuestas.
Expect the worst, is it the least you can do?
Avatar de Usuario
creating021
Perlero frecuente
Perlero frecuente
 
Mensajes: 595
Registrado: 2006-02-23 16:17 @720
Ubicación: Frente al monitor

Notapor elnico » 2008-01-05 20:51 @910

Hola.
La verdad que está muy bueno el ejemplo de kidd sobre Tie::File.

Pero tengo una duda medio tonta: ¿no hace falta instalar ese módulo, no?

Porque lo probé con una versión de Perl sin haberlo instalado y me funcionó sin problemas.

Saludos.
elnico
Perlero nuevo
Perlero nuevo
 
Mensajes: 69
Registrado: 2007-09-09 14:44 @656

Notapor elnico » 2008-01-05 21:01 @917

Me olvidé de aclarar que lo probé en un ActivePerl y lo pienso implementar también en un Linux.
elnico
Perlero nuevo
Perlero nuevo
 
Mensajes: 69
Registrado: 2007-09-09 14:44 @656

Notapor explorer » 2008-01-05 21:53 @953

Es uno de los módulos CORE (módulos que acompañan al binario perl en cada distribución), así que deberá estar.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor elnico » 2008-01-06 06:37 @317

Me quedo más tranquilo.
Gracias por responder.
elnico
Perlero nuevo
Perlero nuevo
 
Mensajes: 69
Registrado: 2007-09-09 14:44 @656


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 7 invitados