• Publicidad

Comparar dos archivos

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

Comparar dos archivos

Notapor Therion777 » 2010-08-30 15:44 @697

Saludos. Soy nuevo en esto del Perl y mi duda es muy básica. Tengo dos archivos.
Archivo 1:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
8=50=50356536
6=50=49351358
7=50=709286
5=50=702400
8=54=390078008
6=54=629567679
7=54=67566209
5=54=84824766
8=56=347390
6=56=153975
7=56=2890
5=56=2196
8=58=413916
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

etc, número de líneas.

Archivo 2
10932=189.209.208.161=9=1=1=Componente3
189.209.208.161=50=1=1=Componente2
etc, etc, etc, número de líneas.

Mi pregunta es cómo comparo el segundo archivo en el campo [2] con el primer archivo, en su campo [2], para tener un tercer archivo donde muestre lo encontrado en el primer archivo.
Algo así

Archivo 3 (en el tercer archivo se encontraron dos coincidencias: el 50 y el 54)

8=50=50356536=6=50=49351358=7=50=709286=5=50=702400
8=54=390078008=6=54=629567679=7=54=67566209=5=54=84824766

etc etc etc.

Leyendo en el foro encontré esto, pero no he logrado hacer la comparación.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. open my $SALIDA, q[>], 'salida.txt';
  2.  
  3. open my $FICHERO1, q[<], 'archivo2.dat';
  4. while (<$FICHERO1>) {
  5.     my $primera_columna = (split q[=])[2];
  6. #print "$primera_columna\n";
  7. #    $campo{ $primera_columna } = 1;
  8. }
  9. open my $FICHERO2, q[<], 'archivo1.tmp';
  10. while (<$FICHERO2>) {
  11.     my $segunda_columna = (split q[=])[1];
  12.     my $tercera_columna = (split q[=])[2];
  13. # print "$segunda_columna\n";
  14.  
  15. if ( $primera_columna=$segunda_columna ) {   # Si no es un campo visto antes
  16.  print $SALIDA $_;                   # Imprimimos toda la línea
  17.     }
  18. }
  19.  
  20. close $FICHERO1;
  21. close $FICHERO2;
  22. close $SALIDA;
  23.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Espero logren ayudarme...

Saludos.
Therion777
Perlero nuevo
Perlero nuevo
 
Mensajes: 14
Registrado: 2010-08-30 15:30 @687

Publicidad

Re: Comparar dos archivos

Notapor explorer » 2010-08-30 16:18 @720

Bienvenido a los foros de Perl en Español, Therion777.

El problema está en la comparación, que no es tal:

$primera_columna = $segunda_columna

En realidad, eso no es una comparación, sino una asignación. Estás asignando el valor de $segunda_columna en $primera_columna.

Las comparaciones, en Perl, se hacen con operadores de comparación, y que además, se diferencian entre comparaciones numéricas ( ==, !=, <, >, <=, >= y <=>) y las alfanuméricas ( eq, ne, lt, gt, le, gt y cmp).

Si sabes que los datos son siempre numéricos, pues usas '=='. Si no lo son, o no estás seguro, pues usas 'eq'.

Más información en perldoc perlop.

Hay un error también muy grave: estás haciendo que la línea leída del primer fichero quede almacenada en la variable por defecto $_, y ese valor se pierde en cuanto entra en el segundo bucle, ya que las líneas del segundo fichero sobreescriben $_, por lo que la línea

print $SALIDA $_;

en realidad estás imprimiendo las líneas del segundo fichero.

Debes separar las líneas de cada fichero. Por ejemplo:

while (my $linea_primer_fichero = <$FICHERO1>) {

Lo que también puedes hacer es leer los ficheros una sola vez, en vez de leer el segundo fichero de forma completa por cada línea del primero. Puedes leer los ficheros y meter la información relevante en arrays, y luego, recorrerles, grabando el resultado en el tercero.
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 dos archivos

Notapor Therion777 » 2010-08-30 18:55 @830

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
if ($desc0[16] == $indice)
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Tenías razón, he logrado filtrar los datos, pero hora me queda un simple problema.

Me quedaron los datos, en un archivo final.txt:

10932=189.209.208.161=141=L001=252554=8=141=60228800=1048576=0=
10932=189.209.208.161=141=L001=252554=6=141=125802522=1048576=0=
10932=189.209.208.161=141=L001=252554=7=141=338700=1048576=0=
10932=189.209.208.161=141=L001=252554=5=141=352203=1048576=0=
10932=189.209.208.161=143=L002=252555=8=143=712715247=1048576=0=
10932=189.209.208.161=143=L002=252555=6=143=504810649=1048576=0=
10932=189.209.208.161=143=L002=252555=7=143=2975840=1048576=0=
10932=189.209.208.161=143=L002=252555=5=143=2305115=1048576=0=

¿Cómo puedo hacer para que en una línea se vea el campo 7 (las negritas)

10932=189.209.208.161=141=L001=252554=141=60228800=1048576=125802522=1048576=338700=1048576=352203=1048576=

y así con las demás lineas?

10932=189.209.208.161=143=L002=252555=8=143=712715247=1048576=0=
10932=189.209.208.161=143=L002=252555=6=143=504810649=1048576=0=
10932=189.209.208.161=143=L214F01GDL002=252555=7=143=2975840=1048576=0=
10932=189.209.208.161=143=L214F01GDL002=252555=5=143=2305115=1048576=0=
Therion777
Perlero nuevo
Perlero nuevo
 
Mensajes: 14
Registrado: 2010-08-30 15:30 @687

Re: Comparar dos archivos

Notapor explorer » 2010-08-30 20:59 @916

Lo indicado antes: leer los ficheros antes, y pasarlos a una estructura de datos interna. De esa manera puedes agregar datos de un mismo campo. Por ejemplo, crear un array donde vamos guardando cada línea (o ciertos campos) donde vamos guardando la información según el valor del segundo campo.

Pero antes habría que aclarar qué consideramos para juntar varias líneas en una sola ¿sólo el segundo campo, o toda la línea? ¿Y si solo es el segundo campo, cómo ha de ser las líneas unificadas?, es decir, ¿cómo se ha de construir la línea resultado?

La estructura de datos la puedes construir así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
    use %campos;
    # ...
    push @{ $campos{ $primera_columna } }, [ $segunda_columna, $tercera_columna ];
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Para ver, temporalmente, el contenido de la estructura de datos, puedes usar el módulo Data::Dumper:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
    use Data::Dumper;
    print Dumper \%campos;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Luego, en la tercera parte del programa, solo hay que recorrer las claves de %campos (aunque saldrán desordenadas, pero tampoco se ha comentado que eso importe).

Más información en perldoc perllol.
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 dos archivos

Notapor Therion777 » 2010-08-31 11:00 @500

explorer escribiste:Lo indicado antes: leer los ficheros antes, y pasarlos a una estructura de
Más información en perldoc perllol.


Creo que esto ya se enredó. Vamos a iniciar.

Yo tengo al inicio dos archivos: A y B; en A tengo datos que quiero comparar con el B.
Eso ya lo hice con el dato del '=='; hasta ahí todo bien, pude crear el archivo C.

Pero necesito darle formato al archivo C
Lo que necesito es saber cómo puedo leer el campo [6] que pongo con negrita y decirle al programa: guarda este dato, lee la segunda línea, y si encuentras el mismo dato, en un archivo nuevo imprime la primera línea y pon al final de la primera línea el campo [6] y [7] negritas de la segunda línea, y así con la tercera línea, etc, etc. Cuando encuentre un número diferente que haga el mismo procedimiento con el mismo número.

10932=189.209.208.161=141=L001=252554=8=141=60228800=1048576=0=
10932=189.209.208.161=141=L001=252554=6=141=125802522=1048576=0=
10932=189.209.208.161=141=L001=252554=7=141=338700=1048576=0=
10932=189.209.208.161=141=L001=252554=5=141=352203=1048576=0=
10932=189.209.208.161=143=L002=252555=8=143=712715247=1048576=0=
10932=189.209.208.161=143=L002=252555=6=143=504810649=1048576=0=
10932=189.209.208.161=143=L002=252555=7=143=2975840=1048576=0=
10932=189.209.208.161=143=L002=252555=5=143=2305115=1048576=0=

Al final debe quedar algo así

10932=189.209.208.161=141=L001=252554=8=141=60883404=1048576=0=1=126192520=1048576=342227=1048576=355635=1048576
Última edición por Therion777 el 2010-08-31 12:11 @549, editado 1 vez en total
Therion777
Perlero nuevo
Perlero nuevo
 
Mensajes: 14
Registrado: 2010-08-30 15:30 @687

Re: Comparar dos archivos

Notapor explorer » 2010-08-31 14:10 @632

El problema que yo tengo, para darte una solución, es que los requisitos no están claros. Veo los distintos ficheros que has publicado y no hay una unanimidad del formato que estás usando. No tenga nada claro cómo es el primer fichero. Ni sé si el segundo fichero tiene las líneas ordenadas con respecto al campo 6. Y mucho menos, cómo se construye cada línea del tercer fichero.

Supongamos que tenemos un primer fichero así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
8=141=50356536
6=142=49351358
6=143=49351358
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
del que solo nos interesa el campo 1. Luego tenemos un segundo fichero así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
10932=189.209.208.161=141=L001=252554=8=141=60228800=1048576=0=
10932=189.209.208.161=141=L001=252554=6=141=125802522=1048576=0=
10932=189.209.208.161=141=L001=252554=7=141=338700=1048576=0=
10932=189.209.208.161=141=L001=252554=5=141=352203=1048576=0=
10932=189.209.208.161=143=L002=252555=8=143=712715247=1048576=0=
10932=189.209.208.161=143=L002=252555=6=143=504810649=1048576=0=
10932=189.209.208.161=143=L002=252555=7=143=2975840=1048576=0=
10932=189.209.208.161=143=L002=252555=5=143=2305115=1048576=0=
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
del que nos interesa los campos 6, 7 y 8. La salida debe ser igual que el segundo fichero, pero aglutinando los campos 7 y 8 a igualdad del campo 6 (y que ese campo también esté presente en el primer fichero). Con el siguiente programa:
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 open ':locale';
  8.  
  9. ## Leemos el primer fichero
  10. my %campo_en_fichero1;
  11. open my $PRIMERO, q[<], 'txt1.txt';
  12.  
  13. while (<$PRIMERO>) {
  14.     my $campo1 = (split /=/)[1];
  15.     $campo_en_fichero1{$campo1} = 1;
  16. }
  17.  
  18. close $PRIMERO;
  19.  
  20. ## Leemos el segundo fichero
  21. my %segundo_fichero;            # aquí guardamos toda la información indexada por el campo 6
  22.  
  23. open my $SEGUNDO, q[<], 'txt2.txt';
  24.  
  25. while (<$SEGUNDO>) {
  26.  
  27.     my $campo6 = (split /=/)[6];
  28.  
  29.     # saltamos si no está en el primer fichero
  30.     next if not $campo_en_fichero1{ $campo6 };
  31.  
  32.     # guardamos la línea, junto con las demás que tienen el mismo campo 6
  33.     push @{ $segundo_fichero{ $campo6 } }, $_;
  34. }
  35.  
  36. close $SEGUNDO;
  37.  
  38. ## Escribimos el tercer fichero
  39. open my $TERCERO, q[>], 'txt3.txt';
  40.  
  41. # sacamos las líneas ordenadas por orden numérico del campo 6
  42. for my $campo6 ( sort { $a <=> $b } keys %segundo_fichero ) {
  43.  
  44.     my @lineas = @{ $segundo_fichero{$campo6} };
  45.  
  46.     # la primera línea la usaremos como plantilla para sacar el resto de la información
  47.     my @campos = split /=/, $lineas[0];
  48.     my $plantilla = join '=', @campos[0..6];    # los primeros 7 campos son iguales
  49.    
  50.     for (@lineas) {
  51.  
  52.         # extraemos los campos 7 y 8
  53.         my ($campo7, $campo8) = (split /=/)[7,8];
  54.        
  55.         # unimos a la plantilla
  56.         $plantilla .= "=$campo7=$campo8";
  57.     }
  58.  
  59.     print $TERCERO "$plantilla\n";
  60. }
  61.  
  62. close $TERCERO;
  63.  
  64. __END__
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

Y sale
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
10932=189.209.208.161=141=L001=252554=8=141=60228800=1048576=125802522=1048576=338700=1048576=352203=1048576
10932=189.209.208.161=143=L002=252555=8=143=712715247=1048576=504810649=1048576=2975840=1048576=2305115=1048576
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

La resolución del programa se basa en usar un hash que va guardando las líneas que tienen todas el mismo campo 6. Es decir: las claves del hash son los nombres del campo 6, mientras que los valores son array, en que cada elemento es una línea que coincide con ese campo.

Luego, en el último bucle, vamos leyendo esos campos, ordenados numéricamente, y vamos sacando esas líneas. De cada una de ellas, creamos una (la llamada $plantilla), y luego, de todas las líneas, sacamos los campos 7 y 8 y vamos agregando toda la información, para sacarla al fichero resultado.

Lo que tiene de complicado es entender la estructura de datos, pero se puede ver fácilmente la forma que tiene si usas el módulo Data::Dumper y sacas el valor de %segundo_fichero: (al final del programa, agrega estas líneas)
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use Data::Dumper;
  2. print Dumper \%segundo_fichero;
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

Re: Comparar dos archivos

Notapor Therion777 » 2010-09-06 16:57 @748

explorer escribiste:El problema que yo tengo, para darte una solución, es que los requisitos no están claros. Veo los distintos ficheros que has publicado y no hay una unanimidad del formato
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use Data::Dumper;
  2. print Dumper \%segundo_fichero;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Domo arigato mister Explorer; es justamente la respuesta, mil gracias; doy por cerrado este caso.

Mil mil mil mil mil gracias.
Therion777
Perlero nuevo
Perlero nuevo
 
Mensajes: 14
Registrado: 2010-08-30 15:30 @687


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado

cron