Mesclar seletivamente o conteúdo do arquivo

0

Eu preciso combinar dois arquivos e imprimir apenas as linhas que depois de caracteres específicos não são seguidas apenas por elementos de um dos arquivos.

Por exemplo, tenho dois arquivos semelhantes a este:

 1A00.pdb_HEM_COA
 1A01.pdb_HEM
 1A05.pdb_IPM
 1A0F.pdb_GTS_4CA
 1A0G.pdb_PMP
 1A0I.pdb_2CP

e isso:

COA
2CP
3CP
3HC
4CA
4CO

Quero associá-los e, se parecer que o primeiro _ é seguido apenas por elementos do segundo arquivo, não os imprima (por exemplo, 1A0I.pdb_2CP ). Se em outras linhas parecer que _ é seguido de algum outro elemento, mas também do elemento do segundo arquivo, basta excluir esse elemento que é comum nos dois arquivos, mas imprimir a linha (o exemplo é 1A00.pdb_HEM_COA e a linha impressa deve ser como 1A00.pdb_HEM ).

Alguém tem alguma ideia de como fazer isso?

    
por djordje 25.01.2018 / 08:03

1 resposta

0

Você pode criar um hash perl das linhas do segundo arquivo

#!/usr/bin/perl -w

use strict;

BEGIN{ $/ = $\ = "\n"; }

my $stringsfile = shift @ARGV;
open(my $fh, '<:encoding(UTF-8)', $stringsfile)
  or die "Could not open file '$stringsfile' $!";

my %h;

while (defined($_ = <$fh>)) {
    chomp $_;
    $h{$_} = 1;
}

e, em seguida, divida as linhas dos primeiros (e subseqüentes) arquivos em campos separados por hífen, grep para os campos que não estão no hash e junte tudo novamente e imprima se o grep retornar alguma coisa:

while (defined($_ = <ARGV>)) { 
    chomp $_;
    my ($x, @F) = split(/_/, $_, 0);
    my @y = grep({not $h{$_};} @F);
    print join('_', $x, @y) if @y;
}

Uso:

$ ./foo.pl file2 file1
 1A00.pdb_HEM
 1A01.pdb_HEM
 1A05.pdb_IPM
 1A0F.pdb_GTS
 1A0G.pdb_PMP

Nota: se as correspondências potenciais estiverem todas no final, há uma abordagem muito mais simples usando awk :

awk '
  BEGIN{OFS=FS="_"} 
  NR==FNR {a[$0]++; next} 
  {while ($NF in a) NF--} 
  NF>1 {print}
' file2 file1

Para os dados de amostra da sua pergunta, as duas abordagens produzem o mesmo resultado.

    
por steeldriver 26.01.2018 / 02:00