seleciona linhas de múltiplas colunas com base em intervalos especificados em um arquivo separado

1

Eu tenho dois arquivos:

arquivo1

ST4.03ch10 56000001 56500000
ST4.03ch11 34500001 35000000
ST4.03ch04 54500001 55000000
ST4.03ch12 500001 1000000

arquivo2

ST4.03ch12 56014301 56019800 0.163 gene 5.5
ST4.03ch12 56022401 56025300 0.419 gene 2.9
ST4.03ch12 671201 803500 1 gene 5.5
ST4.03ch12 671201 803500 1 gene 5.3
ST4.03ch12 671201 803500 1 gene 5.0
ST4.03ch12 447401 449500 0.038 gene 8.5
ST4.03ch12 671201 803500 1 gene 9.5

editado: adicionado parte dos meus dados reais aqui, pois os códigos criados com base nos dados da amostra anterior não funcionaram bem com dados reais.

Eu gostaria de selecionar e imprimir linhas no arquivo2 que correspondem a uma das linhas no arquivo1 nos três critérios a seguir:

1. col1 of file2 = col1 of file1;  
2. col2 of file2 >/= col2 of file1, and  
3. col3 of file2 </= col3 of file1

O que estou tentando fazer é: o arquivo 1 contém identificadores (ST4.03chXX) em col1 e o intervalo de coordenadas correspondente em col2 (o ponto inicial) e col3 (o ponto final), e estou procurando entradas em arquivo 2 que:
1) ter identificadores em colA que correspondam ao identificador no arquivo 1 e ao
2) ter as coordenadas inicial e final (colB e colC) dentro do intervalo no arquivo 1 do respectivo identificador

resultado esperado:

ST4.03ch12 671201 803500 1 gene 5.5
ST4.03ch12 671201 803500 1 gene 5.3
ST4.03ch12 671201 803500 1 gene 5.0
ST4.03ch12 671201 803500 1 gene 9.5

Os arquivos atuais (especialmente o arquivo 2) são muito grandes, então espero realizar o trabalho usando awk , mas o loop, se necessário, também ficará bem.

    
por XYZ1007 16.08.2016 / 21:32

1 resposta

1

Você poderia tentar algo como:

awk 'NR==FNR{z[$1]?z[$1]=z[$1]"|"$2"|"$3:z[$1]=$2"|"$3;next}
{if ($1 in z){l=split(z[$1], k, "|");
{for (i=1;i<l;i+=2){if ($2>=k[i] && $3<=k[i+1]){print}}}}}' file1 file2

file1 , une os campos 2 e 3 com | e salva isso em uma matriz z (indexada pelo primeiro campo), depois lê file2 e verifica se o primeiro campo está em z - se assim for, ele divide z[1st field] em | em k[i] e, para cada valor ímpar de i , imprime a linha se o segundo campo >=k[i] e o terceiro campo <=k[i+1]

    
por 17.08.2016 / 15:05