文字列とその前の21文字をキャプチャしてから、新しいファイルに出力しようとしています。これが私が現在使っているものです:
grep -o ".\{21\}gt" ../data/fastadata.txt > primerdata.txt
目的の出力の一部を取得しましたが、gt
最初の21文字の任意の数字が以前にキャプチャした文字列の一部である場合は、インスタンスをスキップします。たとえば、
aaaatccataaatcgaggattacaagtggaaaacaaggaggcagt
捕獲する
tccataaatcgaggattacaagt
しかし、
caagtggaaaacaaggaggcagt
caagt
2つの文字列がそれぞれ文字列1と2の終わりと始まりを共有しているので、そうだと思います。結局、インスタンスの半分以上が失われました。
この問題をどのように解決できますか?
121個のインスタンスをキャプチャしますが、下のテキストファイルには、...gt
前に21個の文字が付いた約200個のインスタンスがあります。gt
以下は、私が言う内容のインスタンスを含むファイルのいくつかのテキストです(フォーマットのためのハードラッパー)。
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
答え1
私の考えでは問題は正規表現は一致する文字を使用します。。正規表現エンジンが長さゼロのアサーションをサポートしている場合は、この問題をある程度解決できます。
たとえば、必要に応じて計算発生した場合は、単一文字とそれに続く構成で構成されたPCREを使用できます。視野gt
たとえば、GNU grepとそのPCREモードでは(21 - 1)文字で構成されています。
$ printf 'aaaatccataaatcgaggattacaagtggaaaacaaggaggcagt' |
grep -Po '.(?=.{20}gt)'
t
c
一致する各部分文字列の最初の文字を出力して、単一の文字を除くすべての文字が重なり合うようにします。 (結果をwc -l
実際の数にパイプできます)。
実際に一致する文字列を回復する必要がある場合は、文字を消費して消費しないでください。これは明らかに困難です。おそらく一致を返すことでこれを行う方法があります。索引次に、Perlのように部分文字列の一致を実行します(悪いことがあります)。
$ printf 'aaaatccataaatcgaggattacaagtggaaaacaaggaggcagt' |
perl -lne 'while ($_ =~ m/.(?=.{20}gt)/g) {print substr($_,@+[0]-1,23)}'
tccataaatcgaggattacaagt
caagtggaaaacaaggaggcagt