• Publicidad

Perl en archivos de Texto

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

Notapor Kiloko » 2007-10-24 10:03 @460

jajajajajaja, sí, verdad, muy simple, jajajajajaja, pero creo que no me expliqué.

Digamos que $Valor guarda un valor, que cambia constantemente, cada 5 minutos,
y yo quiero guardar en un archivo de texto, estos cambios.

Ejemplo. A las 10:30 $Valor es igual a 30. Así que en el archivo de texto se imprime 30. Pasa el tiempo (tick, tack), y ya son las 10:35 y $Valor ahora es igual a 25. Se abre el archivo y se debe de guardar a un lado del 30, separado por un signo de = quedando así 30=25.

Y así consecutivamente, hasta llegar a 7 valores. Si pasa de 7, el primer valor se borra.

Este sería el resultado a las 11:00PM y $Valor igual a 32
Código: Seleccionar todo
30=34=12=14=43=15=32
y este sería el resultado a las 11:05PM y $Valor igual a 40
Código: Seleccionar todo
34=12=14=43=15=32=40


(todo se recorre de izquierda a derecha)

Saludos
:P
Nunca interrumpas a tu enemigo cuando está cometiendo un error
Napoleón Bonaparte
Avatar de Usuario
Kiloko
Perlero nuevo
Perlero nuevo
 
Mensajes: 243
Registrado: 2007-07-10 18:26 @810
Ubicación: MOnterrey NL

Publicidad

Notapor explorer » 2007-10-24 10:49 @492

Bueno... es normal que nosotros no acertemos con la solución al problema, porque en cada nuevo mensaje tuyo aparecen más y más detalles con nuevas opciones y problemas :-)

En cuanto a lo que planteas ahora, indudablemente debes leer la línea anterior, añadirle el nuevo $Valor, contar los = y si son más de 7, reducirlos. Y grabar la línea.

Todo eso se puede realizar con la expresión regular adecuada:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$linea  = '=30=34=12=14=43=15=32';
$Valor  = 40;
$linea .= "=$Valor";
$linea =~ s/.*?((?:=\d+){1,7})$/$1/; # =34=12=14=43=15=32=40
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor Kiloko » 2007-10-24 10:58 @498

:? tienes razón siempre salgo con nuevas cosas.

Por cierto, recomiendame algún tutorial o dame algún norte de qué es lo que debo buscar porque estoy haciendo varias comparaciones y extrayendo datos, digamos if {} y de estos yo saco un resultado $X y quiero guardar este resultado para utilizarlo posteriormente, pero como cerré las comillas ya no puedo, y si las dejo abiertas pues se sobre corre el proceso.

¿Cómo se podría utilizar? De igual forma, si quiero hacer sub procesos, ¿cómo mandarlos llamar? veo que sí me falta ver un buen conjunto de temas de Perl, :(

Y si me podrías explicar la última línea
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$linea =~ s/.*?((?:=\d+){1,7})$/$1/
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Y ¿cómo busco el tema para ese tipo de comandos?, ¿en que sección o temas de Perl caería?

sALUDOS
Nunca interrumpas a tu enemigo cuando está cometiendo un error
Napoleón Bonaparte
Avatar de Usuario
Kiloko
Perlero nuevo
Perlero nuevo
 
Mensajes: 243
Registrado: 2007-07-10 18:26 @810
Ubicación: MOnterrey NL

Notapor explorer » 2007-10-24 12:00 @541

Kiloko escribiste::? tienes razón siempre salgo con nuevas cosas.
Bueno, ese no es el problema. El problema es que si te damos una solución para una determinada pregunta, quizás no sirva para nada porque la siguiente cuestión o problema es tan determinante que es necesario replantear todo el asunto desde el principio. Pero eso también es bueno, porque así ves lo fácil o difícil que es programar.

Kiloko escribiste:Por cierto, recomiendame algún tutorial o dame algún norte de qué es lo que debo buscar
En este mensaje tienes todos los enlaces necesarios.

Kiloko escribiste:porque estoy haciendo varias comparaciones y extrayendo datos, digamos if {} y de estos yo saco un resultado $X y quiero guardar este resultado para utilizarlo posteriormente, pero como cerré las comillas ya no puedo, y si las dejo abiertas pues se sobre corre el proceso.
Esto no lo entiendo...

Si quieres guardar resultados intermedios, guárdalos en otras variables, con otros nombres.

Kiloko escribiste:¿Cómo se podría utilizar? De igual forma, si quiero hacer sub procesos, ¿cómo mandarlos llamar?
Si es un proceso externo, se puede llamar con do{} (si está escrito en Perl), con qx(), o con system().

Kiloko escribiste:Y si me podrías explicar la última línea
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$linea =~ s/.*?((?:=\d+){1,7})$/$1/
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
De la $linea buscamos de entre 1 a 7 conjuntos de '=' seguido de dígitos (\d) que estén hacia el final ($) de esa $linea. Todo eso lo capturamos con los paréntesis de captura, que queda almacenado en $1, que es al final con lo que nos quedamos. Lo que hay delante de ese texto (.*?), se pierde.

Dicho de otra manera: nos quedamos con los últimos ($) 7 conjuntos de '=' con dígitos. Lo que hay delante, se pierde.

A propósito, aquí entonces hay un error. Decías que la línea es de la forma
Código: Seleccionar todo
12-10-2007=30=34=12=14=43=15=32
Si usamos la anterior expresión regular, borrará todo lo que hay delante, incluso la fecha que hay al principio de la línea.

Si, suponemos, que esa primera parte, es una fecha, y por lo tanto, nunca va a aparecer el caracter '=' dentro de ella, la siguiente expresión regular nos permitirá realizar el corte manteniendo la fecha original:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$linea = '12-10-2007=30=34=12=14=43=15=32';
$Valor = 40;
$linea .= "=$Valor";
$linea =~ s/([^=]+).*?((?:=\d+){1,7})$/$1$2/; # 12-10-2007=34=12=14=43=15=32=40
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
que quiere decir: El primer par de paréntesis se queda con todo (+) aquello que no (^) sea un '='. Luego viene una parte que no nos interesa (.*?) y luego el segundo par de paréntesis son hasta 7 conjuntos de '=' con dígitos. Todo este rollo lo sustituimos por el primer ($1) y el segundo ($2) par de paréntesis capturados antes.

Kiloko escribiste:Y ¿cómo busco el tema para ese tipo de comandos?, ¿en que sección o temas de Perl caería?
Esto último es una de las partes más importantes de Perl: las expresiones regulares. En la documentación estándar de Perl están en los documentos perlre. En los tutoriales (alguno de ellos en esta misma web) en Español también hay abundante información. Incluso Wikipedia tiene un artículo al respecto.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor Kiloko » 2007-10-24 12:57 @581

Excelente ya con eso comienzo a estudiar, :D

Mira el problema completo esta así...

Yo creo un archivo con un grupo de datos. Este es mi código:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
open Data, "info.dat" or die "Error abrir info.dat: $!\n";
my @fichero_A = <Data>;
open Data2, "reglas.dat" or die "Error abrir datos.dat: $!\n";
my @fichero_B = <Data2>;
#---------------------------------------------------------------

foreach $linea2 ( @fichero_A) {
    ($campo1,$campo2,$campo3) = (split /=/, $linea2)[0,1,5];
    @inserta=("$campo1=$campo2=$campo3") ;
    #print"@inserta\n";
    open (Data3, ">>temporal.dat");
    print Data3 "@inserta\n";
    close(Data3);
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


El archivo temporal.dat tiene este contenido:
Código: Seleccionar todo
500=1326=200
500=1326=700
500=1326=100
501=1326=300
500=1326=200=300=500
500=1326=700=180=700
500=1326=100
501=1326=300
502=1326=400
502=1326=300
700=1327=300
701=1327=650
502=1326=400
502=1326=300
700=1327=300
701=1327=650

que salió del archivo info.dat que originalmente tiene este contenido:

500=1326=alarma de las torres=10=25=200=10

Hasta ahí no hay problema.

La cosa está así: info,dat cambia cada 5 minutos. El cambio más dramático está en el campo:


500=1326=alarma de las torres=10=25=200=10

Así que voy a necesitar abrir nuevamente el archivo y leerlo completamente e insertar al final de él el campo 200 con su nuevo valor; digamos que ahora es 300, entonces, info.dat, quedaría así después de 5 minutos (11:00):
Código: Seleccionar todo
500=1326=200=300
500=1326=700=180
500=1326=100
501=1326=300
502=1326=400
502=1326=300
700=1327=300
701=1327=650


Otra cosa es que yo lo planteo como una sola línea aunque son como 500, pero mi mayor problema radica en que se tiene que hacer algún ciclo, para que esto se repita hasta llegar a 7.

Ejemplo. Después de 5 minutos (11:05):
Código: Seleccionar todo
500=1326=200=300=500
500=1326=700=180=700
500=1326=100
501=1326=300
502=1326=400
502=1326=300
700=1327=300
701=1327=650

Como ves, los primeros 2 datos no se mueven para nada, toda la acción comienza a partir de la tercera columna, y eso de llegar a 7 es que esto es lo máximo que puede haber por línea:

500=1326=200=300=500=100=700=300=500

Y si se hace nuevamente la comparación pasados 5 minutos, hace lo que planteé en un post anterior: lo mueve de izquierda a derecha,

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$linea  = '=30=34=12=14=43=15=32';
$Valor  = 40;
$linea .= "=$Valor";
$linea =~ s/.*?((?:=\d+){1,7})$/$1/; # =34=12=14=43=15=32=40
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


:? Está complicado... verdad...
Nunca interrumpas a tu enemigo cuando está cometiendo un error
Napoleón Bonaparte
Avatar de Usuario
Kiloko
Perlero nuevo
Perlero nuevo
 
Mensajes: 243
Registrado: 2007-07-10 18:26 @810
Ubicación: MOnterrey NL

Notapor explorer » 2007-10-24 15:08 @672

Falta decir un dato...

¿Qué es lo que indica qué línea hay que modificar en temporal.dat?

Está claro que hay que leer info.dat, pero, ¿qué línea hay que modificar en temporal.dat?

¿O acaso es una relación uno a uno, es decir, la línea x de info.dat afecta a la línea x de temporal.dat?

Todo lo demás ya lo tienes hecho...
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor Kiloko » 2007-10-24 16:19 @721

Ahora sí que ya me bloqueé

¿Qué es lo que indica qué línea hay que modificar en temporal.dat?


Es algo predefinido, bajo las premisas.

Todo lo que se inserte debe estar después de los primeros dos =

500=1326=200=300=500

Después de esos dos = solo puede haber 6 =.

Ejemplo:

500=1326=700=180=700=500=100=700=800

Está claro que hay que leer info.dat, pero, ¿qué línea hay que modificar en temporal.dat?


En sí no hay que modificar, hay que insertar al final de cada línea, el dato correspondiente, y darle un espacio de 6 como menciono en la parte de arriba y que no sobrepase ese rango.

¿O acaso es una relación uno a uno, es decir, la línea x de info.dat afecta a la línea x de temporal.dat?

Exactamente, afecta línea por línea. :( :(
Nunca interrumpas a tu enemigo cuando está cometiendo un error
Napoleón Bonaparte
Avatar de Usuario
Kiloko
Perlero nuevo
Perlero nuevo
 
Mensajes: 243
Registrado: 2007-07-10 18:26 @810
Ubicación: MOnterrey NL

Notapor explorer » 2007-10-24 18:09 @798

Esta es una posible solución:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;

open INFO, '<info.dat';
my @info = <INFO>;
close INFO;

open TEMPORAL, '<temporal.dat';
my @temporal = <TEMPORAL>;
close TEMPORAL;

# Para todas las líneas
for my $i ( 0 .. $#info ) {

    # Leemos la línea de información y el campo que cambia
    my $info   = $info[ $i ];
    my $campo  = (split /=/, $info)[5];

    # Leemos la línea del temporal
    chomp( my $temporal = $temporal[ $i ] );

    # Construímos la nueva línea de temporal
    #$campo = int rand 200;
    $temporal .= "=$campo\n";
    $temporal =~ s/^(\d+=\d+).*?((?:=\d+){1,7})$/$1$2/;

    # La guardamos
    $temporal[ $i ] = $temporal;
}

open  TEMPORAL, '>temporal.dat';
print TEMPORAL   @temporal;
close TEMPORAL;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor Kiloko » 2007-10-24 18:36 @816

:shock:
Algo por el estilo estaba haciendo. Deja, termino mi intento de código, y lo mando para que me des tu opinión. En cuanto a lo que me mandas, está genial.

Veo que realmente estoy del nabo y que necesito darle una buena repasada a los libros.

Para mi esta es la parte medular, que no pude lograr:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
for my $i ( 0 .. $#info ) {

    # Leemos la línea de información y el campo que cambia
    my $info   = $info[ $i ];
    my $campo  = (split /=/, $info)[5];

    # Leemos la línea del temporal
    chomp( my $temporal = $temporal[ $i ] );
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Bueno, en cuanto termine eso te lo mando para que me des tu opinión. Y mil gracias, por el código.
Nunca interrumpas a tu enemigo cuando está cometiendo un error
Napoleón Bonaparte
Avatar de Usuario
Kiloko
Perlero nuevo
Perlero nuevo
 
Mensajes: 243
Registrado: 2007-07-10 18:26 @810
Ubicación: MOnterrey NL

Repasamos Perl en archivos de texto

Notapor Jenda » 2007-10-29 07:37 @359

Es perfectamente normal tener un array (disculpen, no sé cóomo se dice array en español, estoy aquí para practicar Español, no Perl) que contiene arrays. Así que tu puedes leer los datos así:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my @nombres;
{
  open my $FH, '<', 'X.dat' or die "No puedo leer X.dat: $^E\n";
  while (<$FH>) {
    chomp;
    my @reglon = split /;/, $_;
    push @nombres, \@reglon;
  }
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Ahora tienes todos los números en un array de arrays. Si solo quieres buscar un número entre esos, todo está bien, encima de que podría ser mejor hacer algo así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my @colores = qw(Azul Verde Roja Negra);
my %nombres;
{
  open my $FH, '<', 'X.dat' or die "No puedo leer X.dat: $^E\n";
  while (<$FH>) {
    chomp;
    my @reglon = split /;/, $_;
    $nombres{shift @colores} = \@reglon;
  }
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Ahora, tienes cada grupo de números en un array @{$nombres{Azul}}, etc. y puedes buscarlos entre los números así:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
foreach my $color (keys %nombres) {
  if (grep $_ == $numero, @{$nombres{$color}}) {
   print "Alarma $color\n";
   last;
  }
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Si quieres buscar el color de más números sería mejor usar una estructura diferente:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my @colores = qw(Azul Verde Roja Negra);
my %nombres;
{
  open my $FH, '<', 'X.dat' or die "No puedo leer X.dat: $^E\n";
  while (<$FH>) {
    chomp;
    my $color = shift @colores;
    foreach (split /;/, $_) {
      $nombres{$_} = $color;
    }
  }
}

print "Alarma $nombres{$numero}\n"; # si, es todo
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Lo que he hecho es que he construido una hash usando los números como las llaves y los colores como los valores.

A mí me parece mejor guardar los colores en el archivo así:

Código: Seleccionar todo
Azul;10;11;12;13;14;15;16;17;18;19;20
Verde;21;22;23;24;25;26;27;28;29;30;31
Roja;32;33;34;35;36;37;38;39;40;41;42
Negra;43;44;45;46;47;48;49;50;51;52;53


Con eso tú no tienes que guardar el listín de colores en otro lugar que los números y es muy fácil añadir más colores.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my %nombres;
{
  open my $FH, '<', 'X.dat' or die "No puedo leer X.dat: $^E\n";
  while (<$FH>) {
    chomp;
    my ( $color, @numeros) = split /;/, $_;
    foreach (@numeros) {
      $nombres{$_} = $color;
    }
  }
}

print "Alarma $nombres{$numero}\n";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


¿Qué te parece?
Jenda
Perlero nuevo
Perlero nuevo
 
Mensajes: 132
Registrado: 2007-10-29 06:31 @313
Ubicación: Praga, Republica Checa

Anterior

Volver a Básico

¿Quién está conectado?

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