• Publicidad

Comparar línea con línea siguiente

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

Comparar línea con línea siguiente

Notapor jazstappung » 2012-02-23 13:37 @609

¡Hola!

Necesito comparar entre 2 líneas para saber si son iguales o no en ciertas partes.

Para esto la dividí con split(), pero no sé cómo comparar el valor de la línea 1 con el de la línea 2.

Gracias :D
Avatar de Usuario
jazstappung
Perlero nuevo
Perlero nuevo
 
Mensajes: 6
Registrado: 2012-02-23 13:29 @603
Ubicación: Santiago, Chile

Publicidad

Re: Comparar línea con línea siguiente

Notapor explorer » 2012-02-23 14:07 @630

Bienvenida a los foros de Perl en español, jazstappung.

Si mantienes las partes divididas de la línea 1 en el @array1, y las partes de la línea 2 en el @array2, entonces puedes ver si son iguales, así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. if ($array1[3] eq $array2[4]) {
  2.     ...;
  3. }
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4

Ahí estamos comparando si el cuarto campo de @array1 es igual (alfabéticamente) al quinto campo de @array2. Si en vez de una comparación alfabética, te vale una comparación numérica, cambia 'eq' por '=='.
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

Re: Comparar línea con línea siguiente

Notapor jazstappung » 2012-02-23 14:28 @644

Es que es más que nada lo siguiente:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
A   1   ABC   12
A   4   XYZ   12
A   9   QWE   15
A   8   ASD   18
A   8   POI   12
B   1   AWE    0
B   8   QWD    1
C   3   ZSE   15
D   2   MLP    3
D   0   OKM    4
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Debería tener lo siguiente como salida:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
A   1   ABC   12
A   4   XYZ   12
A   8   POI   12
B   1   AWE    0
C   3   ZSE   15
D   2   MLP    3
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

quedando solo las líneas con el mismo valor en columna 1 y a la vez el menor de la columna 4.

Gracias :D
Avatar de Usuario
jazstappung
Perlero nuevo
Perlero nuevo
 
Mensajes: 6
Registrado: 2012-02-23 13:29 @603
Ubicación: Santiago, Chile

Re: Comparar línea con línea siguiente

Notapor explorer » 2012-02-23 15:26 @684

¿Por qué deben salir tres líneas que empiezan por 'A'? ¿No debería salir solo una, como has dicho?
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

Re: Comparar línea con línea siguiente

Notapor jazstappung » 2012-02-23 15:34 @690

Necesito que sean iguales en columna 1 (nombre) y columna 4 (valor) considerando como patrón la primera línea.

Estoy tomando como base lo siguiente para tomar la línea actual y la próxima.
Sintáxis: [ Descargar ] [ Ocultar ]
  1. while (my $line =<FILE>) {  
  2.     my @data = split(/\|/, $line); 
  3.     my $nextline = <FILE>; 
  4.     print "next line = $nextline"; 
Avatar de Usuario
jazstappung
Perlero nuevo
Perlero nuevo
 
Mensajes: 6
Registrado: 2012-02-23 13:29 @603
Ubicación: Santiago, Chile

Re: Comparar línea con línea siguiente

Notapor explorer » 2012-02-23 17:07 @754

A ver... que no me entero...

Si tenemos que tomar como patrón la primera línea, entonces no deberían salir las líneas B, C y D.

Si la premisa es: «sacar, de las líneas que coinciden en la primera columna, aquellas que tengan el menor valor de la cuarta columna,» entonces la salida debería ser:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
A   1   ABC   12
B   1   AWE    0
C   3   ZSE   15
D   2   MLP    3
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

En cuanto al código presentado, tienes un problema: haces una doble lectura de líneas (<FILE>), con lo que solo estás procesando la mitad del archivo.

Lo mejor es que guardes las líneas en un array:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. open FILE, '<archivo';
  2. my @lineas = <FILE>;
  3. close FILE;
  4.  
  5. for (my $i = 0; $i < @lineas-1; $i++) {       # comparamos la i-ésima línea...
  6.     for (my $j = $i+1; $j < @lineas; $j++) {  # con las j-ésimas líneas siguientes
  7.         # aquí comparamos la línea $lineas[$i] con la $lineas[$j]
  8.         # si la línea $i tiene el mismo campo 1 que la $j, comparamos el cuarto valor
  9.         # si la línea $j tiene un valor menor, guardamos la línea $j en lugar de la $i
  10.         # (la $i va guardando el mínimo) y eliminamos la $j (no es necesaria para la
  11.         # siguiente vuelta de $i)
  12.     }
  13. }
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
Usando índices $i y $j, podemos navegar por el array @lineas.
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

Re: Comparar línea con línea siguiente

Notapor irving » 2012-02-23 18:55 @830

Esto no es muy recomendable hacer con archivos de gran tamaño:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my @lines = split(/\n/, $file);
  2. my $ref;
  3. @{$ref}{map {substr $_, 0, 1} @lines} = map{substr $_, -2, 2} @lines;
  4. print join("\n", map{$_} grep{$ref->{substr $_,0,1} eq substr $_, -2, 2} @lines);
  5.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
Búscame en twitter
Avatar de Usuario
irving
Perlero nuevo
Perlero nuevo
 
Mensajes: 10
Registrado: 2012-02-23 16:01 @709
Ubicación: Chiclayo, Lambayeque, Perú

Re: Comparar línea con línea siguiente

Notapor explorer » 2012-02-23 19:42 @862

Bienvenido a los foros de Perl en español, irving.

La solución que le dí a jazstappung está ajustada al foro en que estamos (Básico).
Comprende que una solución como la tuya, es difícil de entender para alguien que comienza en Perl.

Además, veo que no contempla el caso de quedarse con las líneas que tienen el menor valor de la cuarta columna :wink:

Esto es lo que me sale:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
A   1   ABC   12
A   4   XYZ   12
A   8   POI   12
B   8   QWD    1
C   3   ZSE   15
D   0   OKM    4
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


De todas maneras, muchísimas gracias por tu aporte. Esperamos que no sea el último. :)
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

Re: Comparar línea con línea siguiente

Notapor explorer » 2012-02-23 19:59 @874

Ya que irving ha publicado una solución, yo voy a dar la mía (que no tiene por qué ser la mejor, ni mucho menos).

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use 5.010;
  3. use strict;
  4. use warnings;
  5. use diagnostics;
  6.  
  7. use File::Slurp;
  8.  
  9. my %hash;
  10. my @file = read_file('kk.txt');
  11.  
  12. for (@file) {                                                # Recorremos una vez el fichero,
  13.                                                              # para sacar la estadística de líneas únicas
  14.     my @cols = split;                                        # Dividimos en columnas
  15.    
  16.     if (                                                     # Si...
  17.         not exists $hash{$cols[0]}                           # nunca hemos visto ese primer campo
  18.     or  $hash{$cols[0]} > $cols[3]                           # o la cuarta columna es menor que lo que teníamos,
  19.     ) {
  20.         $hash{$cols[0]} = $cols[3];                          # recordamos ese nuevo valor mínimo (asociado a la 1ª col.)
  21.     }
  22. }
  23.  
  24. for (@file) {                                                # Segundo bucle, para sacar las líneas coincidentes
  25.     my @cols = split;
  26.  
  27.     if (                                                     # Si la línea del archivo...
  28.         exists $hash{$cols[0]}                               # coincide con alguno de los primeros campos
  29.     and $hash{$cols[0]} == $cols[3]                          # y su cuarta columna es también igual
  30.     ) {
  31.         print;                                               # la sacamos en pantalla
  32.     }
  33. }
  34.  
  35. __END__
  36. A   1   ABC   12
  37. A   4   XYZ   12
  38. A   8   POI   12
  39. B   1   AWE    0
  40. C   3   ZSE   15
  41. D   2   MLP    3
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

Re: Comparar línea con línea siguiente

Notapor irving » 2012-02-23 22:30 @979

Fui redirigido desde twitter y no me percaté del nivel del foro, solo vi el problema y me pareció divertido tratar de resolverlo.

Procuraré cumplir con el nivel de cada foro en adelante y comprobar mis soluciones antes de publicarlas. :D
Búscame en twitter
Avatar de Usuario
irving
Perlero nuevo
Perlero nuevo
 
Mensajes: 10
Registrado: 2012-02-23 16:01 @709
Ubicación: Chiclayo, Lambayeque, Perú

Siguiente

Volver a Básico

¿Quién está conectado?

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

cron