Contando um caractere consecutivo específico com sua posição e comprimento de ocorrência

3

Eu tenho um arquivo de seqüência e quero contar o caractere consecutivo "N" com sua posição de ocorrência e o comprimento Digamos que eu tenha um arquivo chamado mySequence.fasta assim:

>sequence-1
ATCGCTAGCATNNNNNNNNNNNNNNCTAGCATCATGCNNNNNNATACGCATCACANNNNNNNNNCgcatATCAC

e saída antecipada deve ser assim:

Position 12 N 14
Position 38 N 6
Position 56 N 9

Por favor, ajude-me a resolver isso por awk ou sed fornecendo meu nome de arquivo mySequence.fasta

    
por Budding-bioinformatician 31.08.2017 / 08:06

2 respostas

9

Você poderia fazer isso com awk , cujo match() que define a variável RSTART e RLENGTH é bastante útil para isso:

<mySequence.fasta awk -v C=N '{
  i=0
  while (match($0, C "+")) {
    printf "Position %d %s %d\n", i+RSTART, C, RLENGTH
    i += RSTART+RLENGTH-1
    $0 = substr($0, RSTART+RLENGTH)
  }}'

Ou com perl usando as matrizes @- e @+ que registram o início e o fim das correspondências:

perl -ne 'printf "Position %d N %d\n", $-[0]+1, $+[0]-$-[0] while /N+/g'

Outra abordagem um pouco mais rápida (pelo menos com a minha versão de perl ) perl usando o operador ( experimental ) (?{...}) regexp:

perl -ne '0 while /N(?{$s=pos})N*(?{printf "Position %d N %s\n", $s, pos()-$s+1})/g'
    
por 31.08.2017 / 08:21
2

Outra solução awk :

awk -F '' '{for(i=1;i<=NF;i++){ if($i=="N"&&!sPOS) sPOS=i;
   if (i==NF &&sPOS && $NF=="N"){LN++}; if($i=="N" &&sPOS && i<NF) {LN++}
   else if(sPOS) {printf("Position %d N %d\n", sPOS, LN); LN=sPOS=0} }
}' infile.txt

Como toda a implementação awk não suporta FS vazio ( -F '' ), abaixo está o script revisado para ser compatível:

awk -F'N' '{sPOS=0;for(i=2;i<=NF;i++){ if($i==""&&!sPOS) sPOS=(i-1)+length($(i-1));
    if($i=="" &&sPOS && NF!=i) {LN++} 
    else if(sPOS) {printf("Position %d N %d\n", sPOS, ++LN); sPOS+=LN+length($i); LN=0} }
}' infile.txt

Exemplo de entrada:

>sequence-1
ATCGCTAGCATNNNNNNNNNNNNNNCTAGCATCATGCNNNNNNATACGCATCACANNNNNNNNNCgcatATCACNN
N
AN
NNA

O resultado é:

Position 12 N 14
Position 38 N 6
Position 56 N 9
Position 75 N 2
Position 1 N 1
Position 2 N 1
Position 1 N 2
    
por 31.08.2017 / 10:01