Como selecionar linhas com base em quantas vezes consecutivas um número está presente em uma coluna?

1

Eu tenho um arquivo assim:

chr1    3000823 3000829 1  
chr1    3001003 3001009 1  
chr1    3001014 3001020 1  
chr1    3001273 3001279 2  
chr1    3001625 3001631 3  
chr1    3003222 3003228 4  
chr1    3003335 3003341 4  
chr1    3003375 3003381 4  
chr1    3003578 3003584 4  
chr1    3003636 3003642 4  
chr1    3003717 3003723 4  
chr1    3003881 3003887 4  
chr1    3003894 3003900 4  
chr1    3004526 3004532 5  
chr1    3005994 3006000 6  
chr1    3006183 3006189 6  
chr1    3006412 3006418 7  
chr1    3006778 3006784 8  
chr1    3006877 3006883 8  
chr1    3007166 3007172 9  
chr1    3007426 3007432 10      
chr1    3007528 3007534 10  
chr1    3007576 3007582 10  

Eu gostaria de ter apenas as linhas que contêm um número específico de vezes qualquer número na quarta coluna.

Digamos que eu gostaria de ter linhas que tenham 3 vezes o mesmo número na quarta coluna, então a saída seria:

chr1    3000823 3000829 1  
chr1    3001003 3001009 1  
chr1    3001014 3001020 1  
chr1    3007426 3007432 10  
chr1    3007528 3007534 10  
chr1    3007576 3007582 10  

.. isso ocorre porque essas linhas têm o número 1 e 10 que estão presentes 3 vezes na quarta coluna

Qualquer ideia seria muito apreciada. Obrigado!

    
por fusion.slope 04.12.2016 / 18:42

2 respostas

3

Uma solução com awk :

awk 'FNR==NR{c[$4]++;next;} c[$4]==3' file.dat file.dat

Saída:

chr1    3000823 3000829 1  
chr1    3001003 3001009 1  
chr1    3001014 3001020 1  
chr1    3007426 3007432 10      
chr1    3007528 3007534 10  
chr1    3007576 3007582 10

Explicação:

  • FNR==NR : este teste é verdadeiro quando o número de registros é igual ao número de registros no arquivo. Isso só é válido para o primeiro arquivo, pois o segundo arquivo NR será igual ao número de linhas do arquivo1 + FNR.
  • c[$4]++ : Incrementa um índice de elemento de matriz em $4 . Eu uso isso como um contador.
  • next : pula para o próximo registro sem fazer mais nada.
  • c[$4]==3 : Isso só acontece nos registros do segundo arquivo. Se esse teste for bem sucedido, a linha será impressa, pois a impressão é a ação padrão em awk .

Este código tem a desvantagem de ler o arquivo duas vezes, mas na minha opinião é uma maneira limpa e fácil de entender para fazer este trabalho.

    
por 04.12.2016 / 19:46
2
{
  i = int(count[$4])
  arr[$4,i] = $0
  count[$4]++
} 

END {
  for (i in count) {
    if (count[i]== n) {
      for (j=0; j<n; j++) {
        printf("%s\n", arr[i,j])
      } 
    } 
  }
}

sample run --

awk -v n=3 -f 1.awk 1.dat 
chr1 3007426 3007432 10
chr1 3007528 3007534 10
chr1 3007576 3007582 10 
chr1 3000823 3000829 1
chr1 3001003 3001009 1
chr1 3001014 3001020 1

awk -v n=8 -f 1.awk 1.dat 
chr1 3003222 3003228 4
chr1 3003335 3003341 4
chr1 3003375 3003381 4
chr1 3003578 3003584 4
chr1 3003636 3003642 4
chr1 3003717 3003723 4
chr1 3003881 3003887 4
    
por 04.12.2016 / 20:27