• Publicidad

Comparar ficheros

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

Comparar ficheros

Notapor m_angeles8 » 2009-03-26 12:54 @579

¡¡Hola a todos!!

La verdad es que mi nivel de Perl es bastante básico. Estoy haciendo un script que en principio no debería ser muy complicado.

Lo que tengo es un fichero del que solo me interesan unas determinadas filas. Una vez identificadas esas filas guardo en diferentes variables el contenido de éstas (en principio el script lo hace bien), luego tengo otro fichero en el que hago algo similar (solo que esta vez me interesan todas las filas, lo único que hago es guardar su contenido en variables).

Mi problema viene al comparar dos variables que he guardado de estos ficheros. Comparar, compara, pero no lo hace bien, pierdo cosas en el camino.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl

#recoge los nombres de los ficheros en la linea de comando
if ( (!$ARGV[0])|| (!$ARGV[1])||(!$ARGV[2])){
        print "La linea de ejecución del programa debe ser: ortologos.pl genesZfin.tsv moddanre.txt ortologos.txt\n";}

$ficherouno = $ARGV[0];
$ficherodos = $ARGV[1];
$ficherotres = $ARGV[2];

$y=1;
$x=1;
$b=1;
$n=1;
$m=1;
$i=1;

open(geneszfin,"$ficherouno") or die "problemas abriendo el fichero $ficherouno\n";
        while (<geneszfin>){
                chomp $_;
                if($_=~/^\w/){
                        chomp $_;
                        my ($genzfin,$ref,$stage,$r,$idzfin)=split(/\t/,$_);
                        $datozfin[$y]=$idzfin."\t".$genzfin."\t".$stage;
                        $zfin[$y]=$idzfin;
                        $y=$y+1;
                        next;}
                last if ($_=~/^FIN/);
        }
        print tres "FIN\n";
close(geneszfin);

$y=$y-1;
print "$y y $zfin[$y]\n";


open(moddanre,"$ficherodos")or die "problemas abriendo el fichero $ficherodos\n";
        while(<moddanre>){
                chomp $_;
                if($_=~/^ZDB/){
                        chomp $_;
                        my ($identificador,$scorea,$r,$id,$scoreb)=split(/\t/,$_);
                        if (($identificador=~/ZDB/)&&($scorea=~/100/) &&($scoreb=~/100/)){
                                $dato[$x]=$identificador."\t".$scorea."\t".$id."\t".$scoreb;
                                $idanimala[$x]=$identificador;
                                $x=$x + 1;
                                next;}
                }
                last if ($_=~/^FIN/);
        }
close(moddanre);

$x=$x-1;       
print "$x y $idanimala[$x]\n";

for ($a=1;$a<=$x;$a++){
        for($b=1;$b<=$y;$b++){
                if ($zfin[$b]=~/$idanimala[$a]/){
                        $match[$n]=$dato[$b];
                        $n=$n+1;}
        }
}

$n=$n-1;
$m=$m-1;
print "$n $match[$n] y $m $mismatch[$m]\n";

open(ortologos,">$ficherotres") or die "problemas abriendo el fichero $ficherotres\n";
        print ortologos "Grupos de ortologos presentes en nuestra lista de Zebra Fish\n";
        for ($a=1;$a<=$n;$a++){
                print ortologos "$match[$a]\n";}
        print tres "FIN\n";
close(ortologo);
exit;
 
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


¡¡Gracias y saludos!!
m_angeles8
Perlero nuevo
Perlero nuevo
 
Mensajes: 8
Registrado: 2009-03-26 12:44 @572

Publicidad

Notapor explorer » 2009-03-26 15:08 @672

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

¿No podrías poner un ejemplo de los ficheros que quieres tratar?

Me temo que puede haber un problema con las variables que hacen de contador.
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 m_angeles8 » 2009-03-26 15:31 @688

¡¡Hola!!

¡¡Gracias por la rapidez!!

El fichero genesZfin.tsv es un listado de genes en el que aparece en cada fila el nombre del gen, referencias, estado, tab, identificador del gen (éste último es el que me interesa guardar para la comparación).

El fichero moddanre lo he obtenido de una base de datos y aparece un listado de grupos de ortologos, donde en cada bloque viene una introducción; más abajo, identificador especie A, %, tab, identificador especie B, %, y al final del bloque vienen un par de frases. El identificador de la especie A es el que en este caso me interesa guardar para comparar.

Pego una parte para aclarar:

Fichero genZfin.tsv:
Código: Seleccionar todo
aacs    1       figure(s) from Thisse et al., 2004      20-25 somites to Prim-5 ZDB-GENE-040426-903
aarsd1  2       figure(s) from Thisse et al., 2004      20-25 somites to Prim-25        ZDB-GENE-040801-91
abca1b  1       figure(s) from Thisse et al., 2001      20-25 somites to Prim-5 ZDB-GENE-030131-9826
abce1   2       figure(s) from Thisse et al., 2004      20-25 somites to Prim-25        ZDB-GENE-040426-1995
acly    2       figure(s) from Thisse et al., 2001      20-25 somites to Prim-25        ZDB-GENE-031113-1


Fichero moddanre.txt:
Código: Seleccionar todo
___________________________________________________________________________________
Group of orthologs #1. Best score 8471 bits
Score difference with first non-orthologous sequence - modDANRE.fa:8335
modMUSMU.fa:6931
ZDB-GENE-030131-7050    100.00% MGI:103147      100.00%
Bootstrap support for ZDB-GENE-030131-7050 as seed ortholog is 100%.
Bootstrap support for MGI:103147 as seed ortholog is 100%.
___________________________________________________________________________________
Group of orthologs #2. Best score 7966 bits
Score difference with first non-orthologous sequence - modDANRE.fa:7966
modMUSMU.fa:7903
ZDB-GENE-030616-132     100.00% MGI:2179432     100.00%
Bootstrap support for ZDB-GENE-030616-132 as seed ortholog is 100%.
Bootstrap support for MGI:2179432 as seed ortholog is 100%.
___________________________________________________________________________________
Group of orthologs #3. Best score 6342 bits
Score difference with first non-orthologous sequence - modDANRE.fa:6342
modMUSMU.fa:5428
ZDB-GENE-041001-165     100.00% MGI:99685       100.00%
                                MGI:99659       6.68%
Bootstrap support for ZDB-GENE-041001-165 as seed ortholog is 100%.
Bootstrap support for MGI:99685 as seed ortholog is 100%.


¡¡¡Gracias!!!
m_angeles8
Perlero nuevo
Perlero nuevo
 
Mensajes: 8
Registrado: 2009-03-26 12:44 @572

Notapor kidd » 2009-03-26 15:32 @689

Como dice Joaquín, será importante ver un ejemplo de los datos que contienen tu fichero. Nada más quería hacerte un par de comentarios en cuanto a tu código:

En tu if tienes:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
($identificador=~/ZDB/) && ($scorea=~/100/) && ($scoreb=~/100/)
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


No sé si sea tu intención usar puras expresiones regulares, pero por ejemplo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$scorea =~ /100/
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


No es lo mismo que comparar igualdad:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$scorea == 100
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Como tienes la comparación, retornará verdadero siempre y cuando existan los caracteres 1,0,0 juntos en alguna parte de la cadena, por tanto será verdadero para los siguiente casos:

Código: Seleccionar todo
100
1000
10000
010000
731000
...


Usando la igualdad, solamente retornará verdadero si $scorea es igual a 100.

Te repito, igual y sea lo que necesitas usando expresiones regulares, pero como lo usas en todas partes, me hace dudar si esto sea así.

Saludos
Uriel Lizama Perl programmer fundador de Perl en Español
Perl Programming Language
Avatar de Usuario
kidd
Creador de Perl en Español
Creador de Perl en Español
 
Mensajes: 1166
Registrado: 2003-10-15 16:52 @744
Ubicación: México

Notapor m_angeles8 » 2009-03-26 15:42 @696

¡¡Hola!!
Gracias por la respuesta, la verdad es que no sabría muy bien qué decirte, la cosa es que lo que he almacenado en $scorea y $scoreb son porcentajes, pero probaré a cambiarlo.

Por otra parte, la comparación yo la hago con los identificadores por eso no sé si eso tiene mucho que ver, lo del 100 solo es porque hay casos en los que el porcentaje es menor y esos no me interesa que los compare.

¡¡¡Saludos!!!
m_angeles8
Perlero nuevo
Perlero nuevo
 
Mensajes: 8
Registrado: 2009-03-26 12:44 @572

Notapor explorer » 2009-03-26 17:12 @758

Varias cosas...

  1. El programa solo funciona si y solo si realmente son caracteres tabulador lo que separa los campos de las líneas que nos interesan. Y solo un carácter de tabulador entre dos campos. Si son más, hay que cambiar las expresiones regulares de los split()
  2. El arreglo @datozfin no se usa por ninguna parte
  3. A la hora de leer el fichero moddanre.txt lo haces pensando que tiene 5 campos separados por tabuladores:
    Sintáxis: [ Descargar ] [ Ocultar ]
    Using perl Syntax Highlighting
    my ($identificador,$scorea,$r,$id,$scoreb)=split(/\t/,$_);
    Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
    pero yo solo veo 4:
    Código: Seleccionar todo
    ZDB-GENE-030616-132     100.00% MGI:2179432     100.00%

  4. En ese mismo fichero hay líneas de coincidencia que nunca contemplamos:
    Código: Seleccionar todo
                                    MGI:99659       6.68%

La siguiente versión funciona si se cumple lo de los tabuladores:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl

if (@ARGV != 3) {
    die "La linea de ejecución del programa debe ser: ortologos.pl genesZfin.tsv moddanre.txt ortologos.txt\n";
}

my ($fichero_genes, $fichero_moddanre, $fichero_ortologos) = @ARGV;

## Leemos el fichero de genesZfin
my @zfin;

open    GENESZFIN,"<$fichero_genes" or die "No puedo abrir el fichero $fichero_genes: $!\n";
while (<GENESZFIN>) {
    last if /^FIN/;

    if (/^\w/) {
        chomp;
        my (undef, undef, undef, undef, $idzfin) = split /\t/;
        push @zfin, $idzfin;
    }
}
close   GENESZFIN;

if (!@zfin) {
    die "No he leído nada de geneszfin. Fin.\n";
}
else {
    print "Leídos ", scalar @zfin, " geneszfin.\n";
}


## Leemos el fichero moddanre
my @dato;
my @idanimala;

open    MODDANRE, "<$fichero_moddanre" or die "No puedo abrir el fichero $fichero_moddanre: $!\n";
while (<MODDANRE>) {
    last if /^FIN/;

    if (/^ZDB/) {
        chomp;
        my ($identificador, $scorea, $id, $scoreb) = split /\t/;

        if ( $scorea eq '100.00%' and $scoreb eq '100.00%' ) {
            push @dato, join "\t", $identificador, $scorea, $id, $scoreb;
            push @idanimala, $identificador;
        }
    }
}
close   MODDANRE;

if (!@idanimala) {
    die "No he leído nada de idanimala. Fin.\n";
}
else {
    print "Leídos ", scalar @idanimala, " idanimala.\n";
}

## Búsqueda de coincidencias
my @match;

for my $i (0 .. $#zfin     ) {
for my $j (0 .. $#idanimala) {
    if ( $zfin[$i] eq $idanimala[$j] ) {
        push @match,       $dato[$j];
    }
}}

if (!@match) {
    print "No hay coincidencias\n";
}
else {
    print "Encontrados ", scalar @match, " coincidencias.\n";

    open  ORTOLOGOS, ">$fichero_ortologos" or die "No puedo escribir en $fichero_ortologos: $!\n";
    print ORTOLOGOS join("\n", @match), "\n";
    close ORTOLOGOS;
}

__END__
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

Fíjate que no hay porqué usar variables contador sobre estructuras de datos (los arreglos), porque los propios arreglos nos dan información sobre ellos.


Si usamos diccionarios, entonces queda un poco más reducido y claro:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl

if (@ARGV != 3) {
    die "La linea de ejecución del programa debe ser: ortologos.pl genesZfin.tsv moddanre.txt ortologos.txt\n";
}

my ($fichero_genes, $fichero_moddanre, $fichero_ortologos) = @ARGV;


## Leemos el fichero de genesZfin
my @zfin;

open    GENESZFIN,"<$fichero_genes" or die "No puedo abrir el fichero $fichero_genes\n";
while (<GENESZFIN>) {
    last if /^FIN/;
    if (/^\w/) {
        chomp;
        push @zfin, (split /\t/)[4];     # guardamos solo el quinto campo
    }
}
close   GENESZFIN;


## Leemos el fichero moddanre
my %idanimala;

open    MODDANRE, "<$fichero_moddanre" or die "No puedo abrir el fichero $fichero_moddanre\n";
while (<MODDANRE>) {
    last if /^FIN/;

    if (/^ZDB/) {
        chomp;
        my ($identificador, $scorea, $id, $scoreb) = split /\t/;
        if ($scorea eq '100.00%' and $scoreb eq '100.00%') {
            $idanimala{$identificador} = $_;
        }
    }
}
close   MODDANRE;


## Búsqueda de coincidencias
open  ORTOLOGOS, ">$fichero_ortologos" or die "No puedo escribir en $fichero_ortologos: $!\n";
for my $gen (@zfin) {
    if ($idanimala{$gen}) {
        print ORTOLOGOS $idanimala{$gen}, "\n";
    }
}
close ORTOLOGOS;
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

Usando diccionarios (hash) la búsqueda se reduce mucho, porque la búsqueda es mirar si existe o no $idanimala correspondiente a cada $gen almacenado en @zfin.
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 m_angeles8 » 2009-03-27 05:00 @250

¡¡Hola!!

No entiendo muy bien cuál es el problema; he probado con el programilla que habéis pasado y me devuelve el mismo resultado que con el que yo tenía antes y sé seguro que hay coincidencias que no me está devolviendo porque he comprobado algunos genes que deberían estar y sin embargo no están. La verdad es que soy bastante novata en esto de Perl.

¡¡¡Gracias y saludos!!!
m_angeles8
Perlero nuevo
Perlero nuevo
 
Mensajes: 8
Registrado: 2009-03-26 12:44 @572

Notapor m_angeles8 » 2009-03-27 05:17 @262

¡¡Hola de nuevo!!

Mirando el fichero de salida me he dado cuenta de que todos los identificadores que ha guardado son de la misma longitud, los que ha perdido son los que tiene otra longitud.

Por ejemplo:

Código: Seleccionar todo
Los identificadores en Zebra fish aparecen de la siguiente manera:
ZDB-GENE-060803-1
ZDB-GENE-030131-9646
ZDB-GENE-041010-114
ZDB-GENE-990415-30


A mi únicamente me guarda los que a partir del último guión llevan tres números (que es como aparece el primer gen que presenta coincidencia), no sé si esto tendrá que ver.
m_angeles8
Perlero nuevo
Perlero nuevo
 
Mensajes: 8
Registrado: 2009-03-26 12:44 @572

Notapor explorer » 2009-03-27 05:50 @285

Entonces el problema es que los campos no están separados por caracteres tabulador.

Usa Data::Dumper para ver el contenido de las estructuras de datos y comprobar que lo han leído de forma correcta.

Por ejemplo, en el último código mío, lo modificamos así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;

use Data::Dumper;

if (@ARGV != 3) {
    die "La linea de ejecución del programa debe ser: ortologos.pl genesZfin.tsv moddanre.txt ortologos.txt\n";
}

my ($fichero_genes, $fichero_moddanre, $fichero_ortologos) = @ARGV;


## Leemos el fichero de genesZfin
my @zfin;

open    GENESZFIN,"<$fichero_genes" or die "No puedo abrir el fichero $fichero_genes\n";
while (<GENESZFIN>) {
    last if /^FIN/;
    if (/^\w/) {
        chomp;
        push @zfin, (split /\t/)[4];     # guardamos solo el quinto campo
    }
}
close   GENESZFIN;

print Dumper \@zfin;


## Leemos el fichero moddanre
my %idanimala;

open    MODDANRE, "<$fichero_moddanre" or die "No puedo abrir el fichero $fichero_moddanre\n";
while (<MODDANRE>) {
    last if /^FIN/;

    if (/^ZDB/) {
        chomp;
        my ($identificador, $scorea, $id, $scoreb) = split /\t/;
        if ($scorea eq '100.00%' and $scoreb eq '100.00%') {
            $idanimala{$identificador} = $_;
        }
    }
}
close   MODDANRE;

print Dumper \%idanimala;

## Búsqueda de coincidencias
open  ORTOLOGOS, ">$fichero_ortologos" or die "No puedo escribir en $fichero_ortologos: $!\n";
for my $gen (@zfin) {
    if ($idanimala{$gen}) {
        print ORTOLOGOS $idanimala{$gen}, "\n";
    }
}
close ORTOLOGOS;

__END__
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
(solo hemos agregado el Data::Dumper y dos sentencias print())

sale:
Código: Seleccionar todo
$VAR1 = [
          'ZDB-GENE-040426-903',
          'ZDB-GENE-040801-91',
          'ZDB-GENE-030131-9826',
          'ZDB-GENE-040426-1995',
          'ZDB-GENE-031113-1'
        ];
$VAR1 = {
          'ZDB-GENE-041001-165' => 'ZDB-GENE-041001-165 100.00% MGI:99685       100.00%',
          'ZDB-GENE-030616-132' => 'ZDB-GENE-030616-132 100.00% MGI:2179432     100.00%',
          'ZDB-GENE-030131-7050' => 'ZDB-GENE-030131-7050       100.00% MGI:103147      100.00%'
        };

En el primero ($VAR1), ves que sale los identificadores que hemos leído del fichero de genes. Y del $VAR2 vemos lo leído del segundo fichero, de forma correcta (las claves son los identificadores y los valores son las líneas enteras leídas del fichero).
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 m_angeles8 » 2009-03-27 07:15 @344

¡¡Hola!!

Siento mucho ser tan pesada pero es que sigo sin entender muy bien qué está pasando. He corrido el último programilla que me has pasado y veo que todo lo lee de forma correcta pero sigo perdiendo cosas en el camino; haciendo comprobaciones al azar he detectado coincidencias que no están en mi fichero salida; ¿qué puedo hacer?

Gracias
m_angeles8
Perlero nuevo
Perlero nuevo
 
Mensajes: 8
Registrado: 2009-03-26 12:44 @572

Siguiente

Volver a Básico

¿Quién está conectado?

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

cron