Perl en Español

  1. Home
  2. Tutoriales
  3. Foro
  4. Artículos
  5. Donativos
  6. Publicidad
 

Cambiar archivo

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Básico
Mensaje Sab Ago 25, 2007 6:51 am
Merisue
Perlero Nuevo
Perlero Nuevo
Registrado: 24 Ago 2007
Mensajes: 19
Cambiar archivo Responder citando

¡Hola a todos!

Veréis, soy una negada para la informática y estoy aprendiendo a programar por primera vez.. Embarassed Y tengo un problemilla para cambiar parte del contenido de un archivo..

A ver si alguno me podéis echar un cable... Es un archivo que lo abro y con la función s/// cambio varios valores del archivo pero no sé cómo cambiarlo en el archivo en sí... No sé si me explico... ¡Ayuda por favorrrrrrr!!

¡¡Gracias a todos!! Very Happy
Mensaje Sab Ago 25, 2007 7:09 am
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4092
Ubicación: Valladolid, España
Responder citando

Bienvenida a los foros de Perl en Español, Merisue.

Se puede hacer de varias maneras. Si, por ejemplo, te lees todo el fichero en memoria, puedes luego abrir el mismo fichero pero en escritura y guardarlo de esta manera con los cambios hechos.

Si, en cambio, vas leyendo línea a línea, deberás antes abrir otro fichero e ir guardando en él las líneas, tanto las no cambiadas como las que sí. Al final, borrar el fichero de partida y al nuevo, darle de nombre el del viejo.

Como esta operación es muy común, Perl ofrece una forma muy cómoda de hacerla, en una sola línea, pero usando los pies.
Mensaje Lun Ago 27, 2007 6:12 am
Merisue
Perlero Nuevo
Perlero Nuevo
Registrado: 24 Ago 2007
Mensajes: 19
Responder citando

¡Muchísimas gracias, explorer, por la ayuda y por tu rápida respuesta! Le he echado un vistazo a los pies pero me vendría mejor hacerlo de alguna de las otras dos maneras ya que lo que quiero es cambiarlo sucesivas veces con un bucle por ejemplo... el problema es que he intentado hacer lo que me sugieres y no lo consigo. me temo que no sé abrirlo en escritura para guardar los cambios.. Embarassed Ya imagino que es algo básico pero no me funciona.. a ver si me podéis dar otro empujoncito... ¡¡Muchísimas gracias!!
Mensaje Lun Ago 27, 2007 7:03 am
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4092
Ubicación: Valladolid, España
Responder citando

Muéstranos el código que te falla, a ver si así descubrimos dónde está el error.

Para abrir un fichero en escritura es lo mismo que en lectura, pero cambiando el '<' por un '>'.
Mensaje Lun Ago 27, 2007 7:47 am
Merisue
Perlero Nuevo
Perlero Nuevo
Registrado: 24 Ago 2007
Mensajes: 19
Responder citando

Muchas gracias ¡lo primero de todo! Bueno, aquí os pongo mi creación frankesnteniana. Me temo que es muy chapucera y ¡debe tener multitud de errores!

Perl:
# Cambiamos el valor de pitch en el archivo_parámetros.
for $i (-4..0){
open (PARAMS, "PARAMS.in") or die "No se pudo abrir PARAMS.in: $!";
for $line (<PARAMS>){
$line  =~ s/(=.\d+/$i)/ or die "No se pudo cambiar el pitch:$!";
  }
close PARAMS;
open (OVERWRITE, ">PARAMS.in");
print OVERWRITE "$line \n" or die "No se pudo sobreescribir PARAMS:$!";
close OVERWRITE;
#Corre el programa prepro y genera un archivo input para FAST.
system ("c:\\perl\\bin\\perl prepro.pl PARAMS.in FAST.template $i.in") or die "No se pudo crear input para FAST: $!";
}
Mensaje Lun Ago 27, 2007 8:23 am
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4092
Ubicación: Valladolid, España
Responder citando

Lo he reescrito, pero no lo he probado:
Perl:
# Cambiamos el valor de pitch en el archivo_parámetros.
for $i ( -4..0 ) {

    # Lugar donde almacenamos el fichero leído y modificado
    my @params;

    # Abrimos el fichero en lectura
    open (PARAMS, "<PARAMS.in") or die "No se pudo abrir PARAMS.in: $!";

    # Para todas las líneas del fichero, hacemos el cambio
    for $line (<PARAMS>) {
        $line  =~ s/=.*\d+/= $i/ or die "No se pudo cambiar el pitch:$!";
        push @params, $line;    # Almacenamos la línea, cambiada o no
    }

    close PARAMS;

    # Grabamos el resultado
    open (OVERWRITE, ">PARAMS.in") or die "No se pudo sobreescribir PARAMS:$!";
    print OVERWRITE @params;
    close OVERWRITE;

    # Corre el programa prepro y genera un archivo input para FAST.
    system ("C:\\perl\\bin\\perl.exe prepro.pl PARAMS.in FAST.template $i.in")
        or die "No se pudo crear input para FAST: $!";
}

Hay dos cambios:
* Había un error en la expresión regular. Los paréntesis estaban mal puestos. La he cambiado por lo que me parece que estás intentando cambiar: aquellas líneas que tienen un '=' seguido de posiblemente varios espacios y seguido de una cifra, cambiarla por la misma línea pero poniendo en lugar de la cifra el valor de $i.
* He usado la variable @params para almacenar todas las líneas leídas del fichero. Luego, se usará para escribir el resultado.

Esto, de forma un poco más moderna, se hace con un sistema de plantillas, que reducen el anterior código a la mitad.
Mensaje Lun Ago 27, 2007 8:33 am
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4092
Ubicación: Valladolid, España
Responder citando

Pregunta curiosa... ¿Cuántas líneas tiene PARAMS.in?
Mensaje Lun Ago 27, 2007 8:42 am
Merisue
Perlero Nuevo
Perlero Nuevo
Registrado: 24 Ago 2007
Mensajes: 19
Responder citando

Ahora mismo solo 6 pero no sé si lo haré mayor o no... Es que voy pasito a pasito dado lo negada que soy... Tengo que generar muchos archivos de input para otro programa cambiando un par de variables pero solo una al tiempo así que creo que no será mucho mayor que ahora; estimo que a lo sumo tendrá unas 10 líneas...

¡¡Muchísimas gracias, ahora mismo te digo si funciona!!
Mensaje Lun Ago 27, 2007 8:54 am
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4092
Ubicación: Valladolid, España
Responder citando

Pues entonces, sí... te merece la pena hacerlo con plantillas... ahorrarás mucho tiempo.

Quizás con el Text::Template te sirva. Si sabes/puedes instalarte este módulo, podemos probar a pasar tu programa a usar plantillas.
Mensaje Lun Ago 27, 2007 9:10 am
Merisue
Perlero Nuevo
Perlero Nuevo
Registrado: 24 Ago 2007
Mensajes: 19
Responder citando

Mmm perdona que te moleste otra vez Embarassed pero me da un pequeño problemilla en la última línea system() me salta la línea de error y me dice que hay un error en dicha línea aunque sí me genera un archivo, el resto del programa va perfecto.. Very Happy Siento ser tan pesada, ¡no me baneeis! Shocked XDDD
Mensaje Lun Ago 27, 2007 9:24 am
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4092
Ubicación: Valladolid, España
Responder citando

¿A qué error te refieres?

Si se trata de un error de sintaxis en el programa, ponlo aquí para que lo veamos.

Si lo que salta es el mensaje del die, es que system() ha devuelto un valor 0, por lo que eso puede significar que el programa que llamas ha funcionado bien. ¿No lo ha hecho?

En definitiva... que estaría bien ver el mensaje de error.

También puedes probar a llamarlo así:
Perl:
system ('C:\perl\bin\perl.exe', 'prepro.pl', 'PARAMS.in', 'FAST.template', "$i.in") == 0
        or die "No se pudo crear input para FAST: $!";

Lo que no sabemos es qué valor debe devolver system() desde el perl.exe que llamas para considerar que ha funcionado o no... en esta última línea he supuesto que si devuelve '0' es que sí ha funcionado bien.
Mensaje Lun Ago 27, 2007 10:05 am
Merisue
Perlero Nuevo
Perlero Nuevo
Registrado: 24 Ago 2007
Mensajes: 19
Responder citando

Lo que salta es el die y efectivamente crea el archivo como se supone que debería. El problema es que al saltar pues no sigue el bucle y no genera el resto de archivos que debería. El mensaje de error es el del die seguido de "at kk1.pl line 22"... kk1 es mi programilla y la línea 22 es la de system(). ¿Quizá debería quitar el die y poner un warning normal para saber si no ha funcionado? Así no pararía el programa...

Por cierto le he echado un vistazo al template que me has dicho y ¡sí parece mucho mejor! el problema es que necesito funcionar con el programa ya, así que quizá me lo mire más adelante con tiempo porque con lo cazurra que soy seguro que me cuesta un poco hacerlo, jejeje. ¡Muchas gracias y perdona de verdad tenerte aquí liado!
Mensaje Lun Ago 27, 2007 10:22 am
Merisue
Perlero Nuevo
Perlero Nuevo
Registrado: 24 Ago 2007
Mensajes: 19
Responder citando

¡Yujuuuuuuu!

¡Le he quitado el or die y funciona! ¡Bien! ¡Muchísimas gracias por todo!

Con un poco de tiempo probaré el template como me has sugerido que seguro que está mucho mejor. ¡No sabes cuanto me has ayudado!

¡Gracias, gracias, gracias! Very Happy Very Happy Very Happy
Mensaje Lun Ago 27, 2007 12:29 pm
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4092
Ubicación: Valladolid, España
Responder citando

Eso quiere decir que seguimos sin saber qué es lo que tiene que devolver prepro.pl.

Si devuelve un 0, puede que signifique éxito, así que deberías cambiar la línea por la última indicada por mí, donde se hace una comparación (== 0).

Si devuelve un valor positivo, debería valer la primera solución, pues entonces suponemos que si devuelve 0, es que ha ocurrido un fallo, y en ese momento se dispara el 'or' del 'die'.

Y como tercera opción... que no nos importe lo que devuelva prepro.pl. Entonces sí que sobraría el 'or die'.
Mensaje Lun Ago 27, 2007 4:47 pm
Merisue
Perlero Nuevo
Perlero Nuevo
Registrado: 24 Ago 2007
Mensajes: 19
Responder citando

Pues sí, parece que tenía que devolver un 0. He añadido la línea que has puesto tú y ¡lo corre sin problema! ¡Gracias!
Publicar nuevo tema   Responder al tema    Foros de discusión -> Básico Todas las horas son GMT - 6 Horas
Página 1 de 1



Powered by phpBB © 2001, 2005 phpBB Group