Listar instâncias sobrepostas de um padrão

6

Estou tentando capturar uma string e os 21 caracteres que a precedem, em seguida, imprima isso em um novo arquivo. Isso é o que estou usando atualmente:

    grep -o ".\{21\}gt" ../data/fastadata.txt > primerdata.txt

E obtenho parte da saída que desejo, mas ela ignora instâncias de gt , quando qualquer valor dos 21 caracteres anteriores fazia parte de uma sequência de captura anterior. Por exemplo:

aaaatccataaatcgaggattacaagtggaaaacaaggaggcagt

irá capturar

tccataaatcgaggattacaagt

mas não

caagtggaaaacaaggaggcagt

Acredito que seja, porque as duas strings compartilham caagt e o final e o início das strings 1 & 2 respectivamente. Ele acaba perdendo pelo menos metade de todas as instâncias.

Como corrijo isso?

Ele captura 121 instâncias de ...gt , mas há algo como 200 instâncias de 21 caracteres anteriores a gt no arquivo de texto abaixo.

Aqui está um texto do arquivo que estou pesquisando que contém instâncias do que estou falando (encadernações para formatação):

aaaccggcctcaagggaacgggtatgtctgcctcacctgtcggagatctacccaatcccagtctgcatct
aacggacactctaatgcaactgctggactgctgcttcctcaccctaacctgcagtggccaaatcgttttg
gtatccaccagcgtggagcagctattgggtcactgtcagtccgatttgtatggccagaatctactgcaga
tcacgcatcccgatgatcaggatctgttaagacagcagctaatacccagggatatagagaccctgttcta
tcagcatcagcaccaccagcagcaggggcacaatccccagcagcactccacttccacgtcggcctcaact
tcgggcagtgatctggaggaggaggaaatggagacggaggaacaccgtctgggtcggcagcagggagagg
cggacgatgacgaggatcacccgtacaaccgacgaacacccagcccgcggagaatggcccatttggcgac
cattgatgaccgactacgcatggatcggcgctgctttaccgtccgcttggctagggcttccacgcgagcg
gaggccacgcgtcattacgagcgggttaagatcgatggctgctttcgtcgcagtgactcctccttaaccg
gaggtgccgctgccaactatccgattgtctcccagctgatacgacgctcgagaaacaacaatatgctggc
tgctgctgcagcagtggcagcagaagcggcgacggtgccgccccagcacgatgccattgcccaggcggcg
ctgcacgggattagcggcaatgatattgtcctggtggccatggccagggtgctgcgagaggaacggccgc
ctgaggagacggagggtacagtgggcttgaccatttacagacagccagaaccctatcagttggagtacca
tacgaggcatctaatcgacggcagcatcatcgactgtgatcaaaggattggtctggtggcgggatatatg
aaggatgaggtgggtatattaacatcatctctctgaactgcttacgacaactaatcgtgtactctccact
cgaaacaggtgcgcaaccttagtcccttctgtttcatgcacctggacgacgttcgctgggtgattgtggc
ccttcgacaaatgtacgattgcaacagtgactacggcgagagctgctaccgtctgctgtcccgcaacggg
cgcttcatttacctgcacaccaagggatttctggaggtcgaccgtggcagtaataaggtgcattcctttc
tgtgcgtcaacacgctgctcgatgaggaggcgggccggcaaaaggtgcaggagatgaaggagaaattctc
gacaatcatcaaggcggagatgcccacgcagagcagcagtcccgatttgcccgcctcgcaggcaccgcag
caacttgagagaattgtcctctatctaatagagaacctacagaagagtgtggattcagcagagacggttg
gcggccagggcatggaaagcctaatggacgatggctacagttcgccagcaaataccttaactctcgagga
gttagctccctcgcccacgcccgccttggccttggtgccgccggctccctcatcggtcaagagctccatc
tccaagtcggtgagtgtggtcaatgtgacggcggccagaaagtttcagcaggagcatcagaagcagcgtg
aacgtgaccgtgagcagcttaaggagcgcaccaactccacgcagggcgtgatccggcaactgagcagctg
cctaagcgaggcggaaacggcatcctgtatcctatcaccagccagtagcttgagtgccagcgaagcaccg
gacacgcccgatccgcacagcaacacatcaccgccaccgtcgctccacacacgtcccagtgtcctgcatc
gaaccctgaccagcacgctgcgatgacgggctgatggaacctggtttgccttctaattgggtgtgtggaa
atggacgtcattggtagctcacgtgcccacaaacgaattagtatcggtaatataatcctggccaatcgca
aaatgaaaacccaaaatgtatcagaaaaaaacgagcattattcaaatagtttaaaaattcagccaaaaaa
cttaaaaacgaaaaaaaagagcgtgggttgaaaaaccttttgttttcatattcacatttccaagctttga
gcaatcaaacaattttaattttcagtatacacatatgtataatgagttggctttacaaaagctattaaca
aatcaagcaattgtgt
    
por candidatezee 08.07.2014 / 22:37

1 resposta

5

Acho que o problema é que a regex consome os caracteres que correspondem a . Você pode ser capaz de contornar isso, até certo ponto, usando asserções de comprimento zero, se o seu mecanismo de regex oferecer suporte a elas.

Por exemplo, se você precisar apenas contar as ocorrências, você pode usar um PCRE que consiste em um único caractere seguido por um lookahead que consiste em (21 - 1) caracteres seguidos por gt , por exemplo no GNU grep com seu modo PCRE,

$ printf 'aaaatccataaatcgaggattacaagtggaaaacaaggaggcagt' | 
grep -Po '.(?=.{20}gt)'
t
c

, que produz o caracter inicial de cada substring correspondente, permitindo sobreposições de todos, exceto de um único caractere. (Você pode canalizar o resultado para wc -l para uma contagem real).

Se você precisar recuperar as sequências de correspondência reais que são obviamente mais difíceis, já que você precisa consumir e não consumir caracteres - provavelmente há uma maneira de fazer isso retornando a correspondência índices e depois fazendo correspondências substring, por exemplo, algo assim em (provavelmente ruim) perl

$ printf 'aaaatccataaatcgaggattacaagtggaaaacaaggaggcagt' | 
perl -lne 'while ($_ =~ m/.(?=.{20}gt)/g) {print substr($_,@+[0]-1,23)}'
tccataaatcgaggattacaagt
caagtggaaaacaaggaggcagt
    
por 09.07.2014 / 00:39

Tags