compara arquivos múltiplos (mais de dois) com duas colunas diferentes

2

Eu tenho quatro arquivos diferentes: file1, file2, file3, file4. Cada arquivo tem duas colunas diferentes separadas por tabulação. Eu quero coincidir com a primeira coluna do arquivo1 (como referência) com a primeira coluna do segundo arquivo, terceiro e quarto arquivo e imprimir a primeira coluna que corresponde e segunda coluna de cada arquivo que tem correspondência primeira coluna. arquivos se parecem com:

arquivo 1

Bm1_00085|Bm1_22625    0.263974289
Bm1_00087|Bm1_22620    0.663443490    

arquivo 2

Bm1_00085|Bm1_22625    0
Bm1_57630|Bm1_52870    0

arquivo 3

Bm1_57630|Bm1_54855    0
Bm1_00085|Bm1_22625    4

arquivo 4

Bm1_57630|Bm1_52870    0
Bm1_00085|Bm1_22625    1

saída:

Bm1_00085|Bm1_22625 0.263974289 0 4 1
    
por n_02 06.07.2015 / 12:40

3 respostas

0

No perl, a ferramenta para este trabalho é um hash. Um hash é um conjunto de pares de valores-chave que torna esse tipo de referência cruzada bastante fácil.

Observação: isso funcionará SOMENTE se o primeiro campo for único:

#!/usr/bin/env perl
use strict;
use warnings;
my %data;

while (<>) {
    my ( $key, $value ) = split;
    push( @{ $data{$key} }, $value );
}

foreach my $key ( sort keys %data ) {
    if ( @{ $data{$key} } >= @ARGV ) {
        print join( "\t", $key, @{ $data{$key} } ), "\n";
    }
}

Invoque como myscript.pl file1 file2 file3 file4 .

  • lê uma lista se houver arquivos da linha de comando via <> e os abre para processamento.
  • Itera uma linha por vez, dividindo a linha em $key e $value .
  • Armazena $value em um hash de matrizes.

  • é executado em cada chave no seu hash

  • se houver elementos numéricos > = número de argumentos da linha de comando (por exemplo, número de arquivos) - imprime essa linha.

Saída disso é:

Bm1_00085|Bm1_22625 0.263974289 0   4   1

Nota:

Assume chaves 'exclusivas' em todos os arquivos.

    
por 06.07.2015 / 14:01
3

Com join e um shell inteligente o suficiente para saber como lidar com <(...) :

join <(sort file1) <(sort file2) | join - <(sort file3) | join - <(sort file4)

Saída:

Bm1_00085|Bm1_22625 0.263974289 0 4 1
    
por 06.07.2015 / 15:02
2

Aqui está uma maneira de fazer isso com o awk:

parse.awk

# Use the first column of the first file as a key and the second column
# as a value in the h hash
NR==FNR { h[$1] = $2; next }

# If $1 is a key in h append $2 to h[$1]
$1 in h { h[$1] = h[$1] OFS $2 }

# When the input has been exhausted, print h key value pairs
# that contain more than one element 
END { for(k in h)
  if(split(h[k], a) > 1)
    print k OFS h[k]
}

Execute assim:

awk -f parse.awk file1 file2 file3 file4

Saída:

Bm1_00085|Bm1_22625 0.263974289 0 4 1
    
por 06.07.2015 / 14:44