计算和删除不同行中的字符

时间:2017-07-17 08:53:26

标签: bash awk sed fastq

我有FASTQ格式的DNA序列数据,每条记录采用4行格式:
@序列报头信息
序列
+
质量得分

序列行中的每个字符在质量得分线中都有相应的字符。所有序列含有8-9个碱基条形码序列,接着是表示生物学序列起始的引物区。在条形码前面,可能存在或不存在一些垃圾桶。我需要根据条形码将序列(及其相关信息)分离到单独的文件中,并在引物之前删除所有内容。对于序列本身,我可以使用grep和sed(a和b是通过在带有样本号的条形码序列文件上循环设置的变量; regexp命中引物):

a=AAAGCG
b=1 
cat DNA.fastq | grep -A2 -B1 -E "${a}""CCTACGGG[ACGT]{1}GGC[AT]{1}GCAG" | grep -v "^--$" | sed -E 's/.+(CCTACGGG[ACGT]{1}GGC[AT]{1}GCAG)/\1/' > sample_${b}.fastq 

这样可以很好地处理这样的输入数据,我想从第2行的开头删除AAAGCG,从第6行的开头删除ATAAAGCG):

@M00816:90:000000000-AE7TD:1:2116:19022:11483 1:N:0:1
AAAGCGCCTACGGGTGGCAGCAGTGGGGAATTTTGGACAATGGGCGCAAGCCTGATCCAGCCATGCCGCGTGTGGGAAGAAGGCCTTCGGGTTGTAAACCACTTTTGTCAGGGAAGAAACGGTCTGAACTAATATTTCGGACTAATGACGGTACCTGAAGAATAAGCACCGGCTAACTACGTGCCAGCAGCCGCGGTAATACGTAGGGTGCAAGCGTTAATCGGAATTACTGGGCGTAAAGCGTGCGCAGGCAGCTTTGCAAGACAGATGTGAAATCCCCGGGCTCAACCTGGGCACTGCA
+
CCCCCGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGFCFGGGGGGGGGGGGGGGGGGGGGGGFGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGFGGGGGGGGGGGGFGGGGGGCFFGGGGGGGGGGGGGGGDGGGGGGGGGGGGGGGGGGGGGGGGGGCAGGGG?FGGGGGGGFGGGG7FG7CGGGGGGGGGGGGEGGGFFFG585C98DEEG?CFG*<<@>37;68CEFCFGF99EGGEEDGE54<9C<8CC>*854C<.
@M00816:90:000000000-AE7TD:1:2118:10209:10682 1:N:0:1
ATAAAGCGCCTACGGGGGGCAGCAGTGGGGAATATTGGACAATGGGCGAAAGCCTGATCCAGCAATGCCGCGTGAGTGATGAAGGCCTTAGGGTTGTAAAGCTCTTTTACCCGGGATGATAATGACAGTACCGGGAGAATAAGCCCCGGCTAACTCCGTGCCAGCAGCCGCGGTAATACGGAGGGGGCTAGCGTTATTCGGAATTACTGGGCGTAAAGCGCACGTAGGCGGCTATTCAAGTCAGAGGTGCAAGCCTGGAGCTCAACTCCAGAACTGCCTTTGAACCTGGATAGCTTGAATCAT
+
--CCCCCGGGGGGGGGGGGGGGGGGFGGGGDEGGGGGGFGGGFGGGGGGGGFGGGG8AEA9DF@FGGGGGGEFGFGFFCFGGG,@FFFG<,<FFGGGGGGDGGGGGGGGFGG7BEE>EDGGGFGFGGFFGGGGGGGGGGGCFGGGC:CGFGGG8,<CEEGGGGFGGGFCE5CEEGGGGGGGGGGGG88C5@CEEE5CCFGGGGGGFGCFGGCG:>G>@FGDCG=F?*1+?E>EE@F@FFG9<9EGGGGG477AFFFDG69F=04C89?FGG7C6CFGG@:EECC8/;;EGC?EC>FF:DA74)

问题是如何从质量得分的开头删除正确数量的字符。在上面的例子中,我需要从第4行(CCCCCG)的开头删除6个字符,从第8行(--CCCCCG)删除8个字符。这可以通过计算条形码之前的碱基数来完成。第2行和第2行的引物4并从乐谱中删除此数量的字符。或者,可以在输出文件上使用第二个命令来计算每个序列的长度(sample_1.fastq中的第2行和第4行)并将质量分数修剪为相同的长度。两者的问题在于它们需要存储来自一行的信息并在后续行的过程中使用它。

创意1:将序列长度存储在单独的文本文件中

cat sample_1.fastq | sed -n '2~4p' | awk 'BEGIN{print length($0)} > seq_lengths.txt' 

这个问题是我无法思考如何与sample_1.fastq中的每条记录同时循环文件的每一行(而不是嵌套循环)。

创意2:

cat sample_1.fastq | awk '$0 == "+" {
a=length $NR-1
b=gensub(/^.{a}/, 1, $NR+1)
print $(NR-2), $(NR-1), $0, b
}' > sample1test.fastq

测试显示长度$ NR-1给出长度-1,而不是前一行的长度! (我还是个新手。)

创意3:计算sample_1.fastq中每个序列行的长度,并在下一行打印。再次捕获文件,grep -B2 -A2这个数字并存储为变量。使用sed将质量得分修剪为变量的值并删除额外的行。这将需要存储变量而不会破坏通过管道的流量,据我所知,这是不可能的。

创意4:将2的倍数设为var1,将4的倍数设为var2。使用awk打印sample_1.fastq行号var1的长度并将其设置为var3。将行var2修剪为长度var3。这需要能够按号码呼叫线路,我理解这也是不可能的。

任何想法或见解将不胜感激!非常感谢。

1 个答案:

答案 0 :(得分:0)

这似乎是一种并非罕见的需求,所以我要做的第一件事就是寻找一个预先写好的实用程序。

谷歌的一些热门点击:

对于像这样的问题,BTW Biostars可能是一个更好的地方。