Sab Ago 25, 2007 6:51 am
|
 |
Merisue
Perlero Nuevo

|
Registrado: 24 Ago 2007
Mensajes: 19
|
|
| Cambiar archivo |
|
|
¡Hola a todos!
Veréis, soy una negada para la informática y estoy aprendiendo a programar por primera vez.. 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!!  |
|
|
|

Sab Ago 25, 2007 7:09 am
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4092
Ubicación: Valladolid, España
|
|
|
|
|
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. |
|

Lun Ago 27, 2007 6:12 am
|
 |
Merisue
Perlero Nuevo

|
Registrado: 24 Ago 2007
Mensajes: 19
|
|
|
|
|
¡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.. Ya imagino que es algo básico pero no me funciona.. a ver si me podéis dar otro empujoncito... ¡¡Muchísimas gracias!! |
|
Lun Ago 27, 2007 7:03 am
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4092
Ubicación: Valladolid, España
|
|
|
|
|
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 '>'. |
|

Lun Ago 27, 2007 7:47 am
|
 |
Merisue
Perlero Nuevo

|
Registrado: 24 Ago 2007
Mensajes: 19
|
|
|
|
|
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: $!";
} |
|
|

Lun Ago 27, 2007 8:23 am
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4092
Ubicación: Valladolid, España
|
|
|
|
|
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. |
|

Lun Ago 27, 2007 8:33 am
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4092
Ubicación: Valladolid, España
|
|
|
|
|
| Pregunta curiosa... ¿Cuántas líneas tiene PARAMS.in? |
|
Lun Ago 27, 2007 8:42 am
|
 |
Merisue
Perlero Nuevo

|
Registrado: 24 Ago 2007
Mensajes: 19
|
|
|
|
|
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!! |
|
Lun Ago 27, 2007 8:54 am
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4092
Ubicación: Valladolid, España
|
|
|
|
|
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. |
|
Lun Ago 27, 2007 9:10 am
|
 |
Merisue
Perlero Nuevo

|
Registrado: 24 Ago 2007
Mensajes: 19
|
|
|
|
|
Mmm perdona que te moleste otra vez 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.. Siento ser tan pesada, ¡no me baneeis! XDDD |
|

Lun Ago 27, 2007 9:24 am
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4092
Ubicación: Valladolid, España
|
|
|
|
|
¿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. |
|

Lun Ago 27, 2007 10:05 am
|
 |
Merisue
Perlero Nuevo

|
Registrado: 24 Ago 2007
Mensajes: 19
|
|
|
|
|
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! |
|

Lun Ago 27, 2007 10:22 am
|
 |
Merisue
Perlero Nuevo

|
Registrado: 24 Ago 2007
Mensajes: 19
|
|
|
|
|
¡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!  |
|
Lun Ago 27, 2007 12:29 pm
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4092
Ubicación: Valladolid, España
|
|
|
|
|
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'. |
|
Lun Ago 27, 2007 4:47 pm
|
 |
Merisue
Perlero Nuevo

|
Registrado: 24 Ago 2007
Mensajes: 19
|
|
|
|
|
| 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! |
|
Powered by phpBB © 2001, 2005 phpBB Group
|