corresponde a colunas e substitui

3

Eu tenho dois arquivos de texto muito grandes com campos delimitados por espaço:

Arquivo1

527858  51  2   27.92464882 8.63E-07
570289  82  2   30.12532071 2.87E-07
571034  90  2   29.26089611 4.43E-07
571033  90  2   28.56723908 6.26E-07
452403  104 2   28.27577506 7.24E-07
351390  100 2   28.16226794 7.67E-07
527858  50  2   27.92464882 8.63E-07

Arquivo2

527858  rs435           
570289  rs564           
571034  rs654           
571033  rs345           
452403  rs665           
351390  rs787           
527858  rs435           

saída:

rs435   51  2   27.92464882 8.63E-07
rs564   82  2   30.12532071 2.87E-07
rs654   90  2   29.26089611 4.43E-07
rs345   90  2   28.56723908 6.26E-07
rs665   104 2   28.27577506 7.24E-07
rs787   100 2   28.16226794 7.67E-07
rs435   50  2   27.92464882 8.63E-07

Compare a primeira coluna do arquivo1 e arquivo2 e substitua a primeira coluna do arquivo1 pelos nomes na coluna 2 nd do arquivo2.

    
por H.K 14.03.2016 / 17:34

2 respostas

0

Veja a mesma ideia básica do awk na resposta do Archemar , implementada em Perl:

$ perl -lane '$#F>1?print"$l{$F[0]} @F[1..$#F]":($l{$F[0]}=$F[1])' file2 file1
rs435 51 2 27.92464882 8.63E-07
rs564 82 2 30.12532071 2.87E-07
rs654 90 2 29.26089611 4.43E-07
rs345 90 2 28.56723908 6.26E-07
rs665 104 2 28.27577506 7.24E-07
rs787 100 2 28.16226794 7.67E-07
rs435 50 2 27.92464882 8.63E-07

Explicação

  • -lane : o -l adiciona uma nova linha a cada print chamada e remove novas linhas finais de cada linha de entrada. O -a faz perl agir como awk : ele dividirá automaticamente cada linha de entrada na matriz @F . Então, o primeiro campo será $F[0] , o segundo $F[1] etc. O -n diz ao perl para ler seu (s) arquivo (s) de entrada linha por linha e aplicar o script dado com -e a cada um deles.

  • $#F>1? ... : ... : este é um operador condicional de estilo C. O formato geral é condition ? foo : bar , o que significa "se condition for true, do foo e, se não for, bar . O $#F é o número de índices da matriz na matriz @F . Como as matrizes começam em 0 , um valor de 1 significa uma matriz com dois elementos.Então, isso executará o primeiro bloco ( print ... , veja abaixo) se houver mais de 2 elementos na matriz, que será só será verdade para file1 .

  • ($l{$F[0]}=$F[1]) : isso é executado para cada linha do arquivo2, para cada linha com menos de 3 campos. Ele preenche o hash %l , cujas chaves são os primeiros campos numéricos de file2 e cujos valores são os rsIDs associados.
  • print"$l{$F[0]} @F[1..$#F]" : imprime o rsID salvo no hash %l para este primeiro campo ( $l{$F[0]} ), um espaço e o restante dos campos nessa linha ( $F[1..$#F] ).

Pessoalmente, provavelmente usaria a solução awk ou, na pior das hipóteses, a perl que forneci, uma vez que eles não precisam que os arquivos sejam classificados. No entanto, desde que você marcou com join , veja como fazer isso usando essa ferramenta:

$ join -o 2.2 1.2 1.3 1.4 1.5 <(sort file1) <(sort file2)
rs787 100 2 28.16226794 7.67E-07
rs665 104 2 28.27577506 7.24E-07
rs435 50 2 27.92464882 8.63E-07
rs435 50 2 27.92464882 8.63E-07
rs435 51 2 27.92464882 8.63E-07
rs435 51 2 27.92464882 8.63E-07
rs564 82 2 30.12532071 2.87E-07
rs345 90 2 28.56723908 6.26E-07
rs654 90 2 29.26089611 4.43E-07
    
por 14.03.2016 / 18:30
2

Eu tentaria

awk 'FNR==NR { F2[$1]=$2 ; next } $1 in F2 {$1 = F2[$1] ; print } ' File2 File1

onde

  • FNR==NR { F2[$1]=$2 ; next } armazena valores do Arquivo1
  • $1 = F2[$1] substituir chave
por 14.03.2016 / 17:41