Mesclando colunas específicas de 2 arquivos com base na correspondência de campo

2

Eu sei que não sou o primeiro a perguntar isto, mas o meu código ainda não funciona:

Arquivo 1:

gi|1283| tRNAscan exon 87020 88058 . - . transcript_id "Parent=tRNA-Tyr5.r01";
gi|3283| tRNAscan exon 97020 97058 . + . transcript_id "Parent=tRNA-Tyr6.r01";
gi|4283| rRNAscan exon 197020 197058 . - . transcript_id "Parent=rRNA-Tyr1.r01";
gi|5283| mRNAscan exon 295020 298059 . + . transcript_id "Parent=mRNA-Tyr2.r01";

Este arquivo é separado por tabulações.

Arquivo 2:

"Parent=tRNA-Tyr6.r01"; 12
"Parent=mRNA-Tyr2.r01"; 0

Este arquivo também é separado por tabulações.

Saída desejada:

"Parent=tRNA-Tyr6.r01"; 12 -
"Parent=mRNA-Tyr2.r01"; 0 +

Eu quero mesclar esses dois arquivos com base na coluna $ 10 no arquivo 1 ( "Parent=tRNA-Tyr6.r01"; ) e coluna $ 1 no arquivo 2 ( "Parent=tRNA-Tyr6.r01"; ), anexando a coluna $ 7 do arquivo 1 ( - / + )

Minha solução seria assim:

awk 'FNR==NR{a[$10]=$7;next} ($1 in a) {print $1,"2,a[$1]}' file2 file1 > Output

Alguém pode me ajudar?

    
por user175863 20.06.2016 / 10:10

1 resposta

1

O utilitário join mescla linhas de dois arquivos baseados em uma coluna comum. Requer que os arquivos sejam classificados nessa coluna.

join -t $'\t' -1 10 -2 1 -o 2.1,2.2,1.7 <(sort -t $'\t' -k10 file1) <(sort -t $'\t' file2)
  • $'\t' é um caractere de tabulação, -t $'\t' diz para usar isso como o separador de campo.
  • join -1 10 -2 1 significa juntar linhas quando o campo 10 do primeiro arquivo corresponde ao campo 1 do segundo arquivo.
  • -o … lista os campos a serem impressos.
  • <(sort …) usa a saída do comando sort como uma das entradas de join .

$'…' e <(…) requerem ksh ou bash, eles não funcionam de forma simples.

Se file2 já estiver classificado, você poderá usá-lo, o que funciona na forma sh:

sort -t $'\t' -k10 file1 |
join -t "$(printf \t)" -1 10 -2 1 -o 2.1,2.2,1.7 - file2

Se você deseja preservar a ordem de um dos arquivos, ainda é possível usar join , mas primeiro adicionar números de linha e, no final, classificar pelos números de linha originais. Por exemplo, para preservar a ordem de file2 :

join -t $'\t' -1 10 -2 1 -o 2.1,2.2,2.3,1.7 \
     <(sort -t $'\t' -k10 file1) \
     <(<file2 nl | sort -t $'\t' -k 2,2) |
sort | cut -d $'\t' -f 2-
    
por 21.06.2016 / 02:18