[Rio-pm] extraindo strings de um arquivo

Gabriel Vieira gabriel.vieira em gmail.com
Domingo Junho 3 21:43:23 PDT 2012


Vamos lá então..

Pra ordenar sugiro que você guarde as chaves encontradas em um
@array.. então para imprimir na ordem em que foram encontradas é só
percorrer o @array, obter o valor e utilizá-lo como chave no %hash.

Para evitar chaves repetidas, antes de adicionar ao array, verifique
se a chave em questão já existe, e consequentemente já foi adicionada
ao array:

push @array, $key unless exists $hash{$key};

Simples. Você pode utilizar tied hash também..

Quanto à solução que você não entendeu, acredito ser a 2a sugestão,
ela consiste em:

A variável temporária está definida?

Sim: Então ela é definida pela conteúdo da linha anterior, devo
trabalhar com ela e com a linha que estou lendo agora e depois aplicar
undef sobre a variável temporária.

Não: Então devo definí-la com o conteúdo da linha que estou lendo e
pular o programa para a próxima linha.


Ficou mais claro?

Abraços,

2012/6/4 André Torres <andretorresrj em gmail.com>:
> Gabriel e Breno,
>
> Obrigado pelas respostas super úteis.
> Entao, eu fiz as modificações que vcs me sugeriram. O fato de colocar a hash
> para ordenar os 2 valores em função do nome foi ótimo, pq ja vou saber que
> nomes tiveram mais de duas repetições para "triad" e "binding". Agora, tenho
> uma duvida como os valores sao lidos e guardados na hash, pois o meu output
> nao sai ordenado pelo nome como no arquivo input. eu fiz algo errado, ou
> existe uma forma de deixar a lista ordenada pelos nomes da mesma forma que o
> input?
> em relação ao resto do codigo, eu cosegui compreender as soluções, exceto
> por uma das soluções que o Gabriel deu em relação a ler a nova antiga e a
> linha atual.
> o código modificado vai no final do texto.
>
> Muito obrigado.
>
> André Torres.
>
>
> exemplo de input X output:
> input:
> name
> 32
> 45
> 65
> ...
>
> output:
> name
> 65
> 32
> 45
> ...
>
> ________________________________________________________________________
> #!/usr/bin/perl
> use strict;
> use warnings;
>
> #my $hmm_name = $ARGV[0];
> my @name_seq;
> my $line;
> #my $linha_atual;
> #my $linha_anterior;
> my $triad;
> my $T;
> my $BP;
> my $hmm_name = shift;
>
> open my $fh, '<', $hmm_name or die "Error: $!";
> my %sequencias = ();
> while (<$fh>){
>    next unless /^Q#/;
>    my @name_seq = split /\s+/;
>        if ($name_seq[5] eq 'triad' or $name_seq[5] eq 'binding'){
>        $triad = $name_seq[-4];
>        }
>        else{
>        print "nao existe triade ou binding poket"; #caso $triad recupere
> algum valor diferente de 'triad' ou 'binding'
>        }
>        $sequencias{$name_seq[2]} .='|***'. $triad; #define $name_seq[2] como
> a chave
> }
>           foreach my $seq (keys %sequencias){ # o valor de cada chave
> organizada na hash é passada para a variavel $seq.
>           print $seq . $sequencias{ $seq } . "\n"; #imprime a chave e os
> campos relacionados a cada uma.
>           }
> close $fh;
> exit;
> ___________________________________________________________________________________
>
>
>
>
>
> Em 2 de junho de 2012 18:34, breno <breno em rio.pm.org> escreveu:
>>
>> Boa Gabriel!
>>
>> André, usando as dicas dele, que tal a seguinte versão:
>>
>> ------------------->8-------------------
>> my $hmm_name = shift;
>>
>> open my $fh, '<', $hmm_name
>>  or die "Error: $!";
>>
>> my %sequencias = ();
>>
>> while (<$fh>) {
>>  next unless /^Q#/;
>>
>>  my @name_seq = split /\s+/;
>>
>>  my ($name_seq, $triad) = @name_seq[2,5];
>>
>>  if ($triad eq 'triad' or $triad eq 'binding') {
>>    $sequencias{ $name_seq } .= '|' . $name_seq[-4];
>>  }
>> }
>>
>> foreach my $seq (keys %sequencias) {
>>  print $seq . $sequencias{ $seq } . "\n";
>> }
>>
>> close $fh;
>> -------------------8<-------------------
>>
>> Você consegue entender o que cada parte está fazendo? Isso te atende?
>> Preste atenção nas dicas do Gabriel e não deixe de responder se tiver
>> alguma dúvida!
>>
>>
>> []s
>>
>> -b
>>
>> 2012/6/2 Gabriel Vieira <gabriel.vieira em gmail.com>:
>> > 1) Sempre inicie os seus programas com:
>> >
>> > use strict;
>> > use warnings;
>> >
>> >
>> > 2) Use o open com 3 parâmetros:
>> >
>> > open my $f, '<', $hmm_name or die "Error: $!";
>> >
>> >
>> > 3) Evite usar a variável especial $_, declare uma variável para
>> > receber o conteúdo:
>> >
>> > while ( my $line = <$f> ) {
>> >
>> > 4) Declare suas variáveis, sempre:
>> >
>> >      my @name_seq = split /\s+/, $line;
>> >      my $name_seq   = $name_seq[2];
>> >      my $triad            = $name_seq[5];
>> >
>> >
>> > 5) == é comparador numérico:
>> >
>> > perl -E 'my $a = "b"; say $a == "a"'
>> >
>> > Sempre que os dois valores estiverem preenchidos por valores não
>> > numéricos irá retornar 1 (verdadeiro).
>> >
>> >
>> > 6) = é atribuição de valor:
>> >
>> > if ( my $x = "oi" ) { print $x }
>> >
>> > Sempre irá atribuir o valor do lado direito à variável e validar esse
>> > valor. Se for 0 ou undef, será falso, para todas as outras existe
>> > mastercard.. ops.. será verdadeiro.
>> >
>> >
>> > 7) Você atribuiu um valor a @T em 2 condições, qual seria o valor de
>> > @T caso elas não fossem atendidas?
>> >
>> >
>> > Dito isso, e pedindo ajuda aos monges caso eu tenha escrito alguma
>> > besteira, vamos à resposta da sua pergunta.
>> >
>> > Vejo algumas soluções de imediato:
>> >
>> > 1) Utilização de HASH, onde o valor em comum às linhas seria a chave:
>> >
>> > push @{ $hash{">AAEL000511-PA"}, "S327,E453,H567";
>> >
>> > Claro, isso com as variáveis no lugar das constantes.
>> > Isso implica em memória, então você avalia se vale a pena.
>> >
>> >
>> > 2) Utilização de uma variável temporária para armazenar a linha atual
>> > e ser lida junto com a próxima:
>> >
>> > my $linha_anterior;
>> >
>> > while ( my $linha_atual = <$f> ) {
>> >
>> >  if ( defined $linha_anterior ) {
>> >      print $linha_anterior . $linha_atual;
>> >      undef $linha_anterior;
>> >   }
>> >   else {
>> >      $linha_anterior = $linha_atual;
>> >   }
>> >
>> > }
>> >
>> >
>> > 3) Faça nova leitura do stream (mais elegante, IMHO):
>> >
>> > while ( my $linha_anterior = <$f> ) {
>> >   my $linha_atual = <$f>;
>> > }
>> >
>> >
>> > 4) Existem outras maneiras...
>> >
>> >
>> > É isso...
>> >
>> > 2012/6/2 André Torres <andretorresrj em gmail.com>:
>> >> oi pessoal,
>> >>
>> >> estou com uma duvida.
>> >>
>> >> eu estou extraindo duas colunas de um arquivo texto, mas gostaria de
>> >> deixar
>> >> elas organizadas em apenas em uma linha e nao em duas como estoa no
>> >> arquivo
>> >> original. nao sei como fazer para o que eu li na primeira linha ser
>> >> colocado
>> >> junto o que for lido na segunda.
>> >>
>> >> ai embaixo vai um exemplo da entrada e da saida que eu estou tendo e a
>> >> que
>> >> eu queria.
>> >>
>> >> obrigado.
>> >>
>> >> input:
>> >> Q#1 - >AAEL000511-PA     specific    catalytic triad    S327,E453,H567
>> >> 3    3    29383
>> >> Q#1 - >AAEL000511-PA     specific    substrate binding pocket
>> >> G245,G246,G247,E326,S327,A328,V331,A482,L486,N487,V522,G568,I571    13
>> >> 13    29383
>> >>
>> >> output que estou tendo:
>> >> AAEL000511-PA S327,E453,H567
>> >> AAEL000511-PA
>> >> G245,G246,G247,E326,S327,A328,V331,A482,L486,N487,V522,G568,I571
>> >>
>> >> output desejado:
>> >>>AAEL000511-PA | S327,E453,H567 |
>> >>> G245,G246,G247,E326,S327,A328,V331,A482,L486,N487,V522,G568,I571
>> >>
>> >> codigo:
>> >>
>> >> open (READ, "$hmm_name") or die ("Error: $!");
>> >>
>> >> while (<READ>)
>> >> {
>> >>     if ($_ =~/^Q#/) {
>> >>        @name_seq = split (" ", $_);
>> >>        $name_seq = $name_seq[2];
>> >>        $triad = $name_seq[5];
>> >>        }
>> >>        if ($triad == "triad"){
>> >>        @T = $name_seq[-4];
>> >>        }
>> >>            elsif ($triad = "binding"){
>> >>            @T = $name_seq[-4];
>> >>            }
>> >> print "@T\n";
>> >> }
>> >> close (READ);
>> >>
>> >>
>> >>
>> >> --
>> >> André Torres
>> >>
>> >> "Quando o homem aprender a respeitar até o menor ser da criação, seja
>> >> animal
>> >> ou vegetal, ninguém precisará ensiná-lo a amar seu semelhante." (Albert
>> >> Schweitzer - Nobel da Paz de 1952)
>> >>
>> >> _______________________________________________
>> >> Rio-pm mailing list
>> >> Rio-pm em pm.org
>> >> http://mail.pm.org/mailman/listinfo/rio-pm
>> >
>> >
>> >
>> > --
>> > Gabriel Vieira
>> > _______________________________________________
>> > Rio-pm mailing list
>> > Rio-pm em pm.org
>> > http://mail.pm.org/mailman/listinfo/rio-pm
>> _______________________________________________
>> Rio-pm mailing list
>> Rio-pm em pm.org
>> http://mail.pm.org/mailman/listinfo/rio-pm
>
>
>
>
> --
> André Torres
>
> "Quando o homem aprender a respeitar até o menor ser da criação, seja animal
> ou vegetal, ninguém precisará ensiná-lo a amar seu semelhante." (Albert
> Schweitzer - Nobel da Paz de 1952)
>
> _______________________________________________
> Rio-pm mailing list
> Rio-pm em pm.org
> http://mail.pm.org/mailman/listinfo/rio-pm



-- 
Gabriel Vieira


Mais detalhes sobre a lista de discussão Rio-pm