【发布时间】:2021-03-18 05:27:38
【问题描述】:
我正在尝试将一个文件中的字符串与另一个文件进行匹配,以获取匹配的行以及前两行和下两行。
我可以用 grep 来处理一个chuck文件,但是会在原始文件(200M 行的键和一个 2TB 的输入源文件)上耗尽内存。
grep --no-group-separator -A 2 -B 1 -f key source
示例密钥文件
^CNACCCAAGGCTCATT
^ANAGCGGCAACTCGCG
我在每一行都添加了“^”,因为关键是在以“@”开头的行旁边的起始 16 个字符
图案由长度为 16 的字符 ATGCN 组成,它们是随机的。源文件中可能有多个匹配模式
对文件的示例搜索
@A00354:427:HVYWLDSXY:1:1101:1036:1000 1:N:0:ATTACTTC
CNACCCAAGGCTCATTCATTATATAGTGGAGGCGGAGAACTTTCCTCCGGTTTGCCTAACATGCCAGCTGTCGGTGTCAAAACCGGCGGATCTCGGGAAGGGGGTCCTGAACTGTGCGTCTTAGGTCGATGGTAATAGGAGACGGGGGAC
+
:#:FFFFFF:F,FFFFFFF:FFF,FF:FFFFFF,FFFFFFFFFFFFFFFF:FFFF:FFFFFFFF:FFFFF,FFF:FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:F,F:FFFFFFFFFFFFFF:F:F,:F:FFFFFFFFFFF:FFF
@A00354:427:HVYWLDSXY:1:1101:1108:1000 1:N:0:ATTACTTC
ANAGCGGCAACTCGCGGTTCCCCTACACATAGAAAACCTACGCCACATTATTGGCTAGGACGAGTGGTTCGTCTGCGTACGCAAGATTGTTGAGATCCACTATTGTCATTCAGTACTACGGTTCTTCTTATCTTGGTCGATCGTGTAAAA
+
F#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:FFFFFFFFFFFFFF,FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF,FFFFFFFFFFFFFF
@A00354:427:HVYWLDSXY:1:1101:1271:1000 1:N:0:ATTACTTC
CNATCCCGTCTCGAGCCCGCCCCAATAGCAACAACAACAACAACAACAACAACAACAGCAACAACACCAGCAACACCAGCAACAACAGCAACAACAACAACAGCAACAACAACAACAACAACAACAACAACAACAACAACAACAACAAGA
+
F#FFFFFFFFFFFFFFFFFFFFFFFF:FFFFFFFF:FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:FFFFFFFFFFFF:FFFFFFFFFFFFFFFFFFF,FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
@A00354:427:HVYWLDSXY:1:1101:1325:1000 1:N:0:ATTACTTC
TNCGGTTCATAGGAATGTAGTCTTTGTAATTATGCGCAATTTCCAAACACTTCAAGGTTTTTTTGCAAATAAAACATTCAGGCCTCGTGTGTGCCGCTGCATCTTAGATCCAACGGCTCCTAGTTGCTCATATTCNACCCAAGGCTCATTAGGTGCTCCCCGTAGC
+
:#FFF:F,FFFFFFFFFFFF,:FFF::F,FFF,F:FFFFFFF:FFFF:FF:F:FFF:F:F:FFFFFFFF,FF,F:FF:FF::F,FFF:FFFFFF,:F::FFFFFFF:FF:FFFFF,FFFFFF,FFF:FFFFFFFFF,FFFF:FFFFFFF:
即使我拆分密钥文件,它的速度也非常慢。
使用 perl one-liner 或 awk 可以更有效地完成吗?
预期的输出是
@A00354:427:HVYWLDSXY:1:1101:1036:1000 1:N:0:ATTACTTC CNACCCAAGGCTCATTCATTATATAGTGGAGGCGGAGAACTTTCCTCCGGTTTGCCTAACATGCCAGCTGTCGGTGTCAAAACCGGCGGATCTCGGGAAGGGGGTCCTGAACTGTGCGTCTTAGGTCGATGGTAATAGGAGACGGGGGAC + :#:FFFFFF:F,FFFFFFF:FFF,FF:FFFFFF,FFFFFFFFFFFFFFFF:FFFF:FFFFFFFF:FFFFF,FFF:FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:F,F:FFFFFFFFFFFFFF:F:F,:F:FFFFFFFFFFF:FFF @A00354:427:HVYWLDSXY:1:1101:1108:1000 1:N:0:ATTACTTC ANAGCGGCAACTCGCGGTTCCCCTACACATAGAAAACCTACGCCACATTATTGGCTAGGACGAGTGGTTCGTCTGCGTACGCAAGATTGTTGAGATCCACTATTGTCATTCAGTACTACGGTTCTTCTTATCTTGGTCGATCGTGTAAAA + F#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF我看到了类似的代码
awk 'NR==FNR{a[$1]; next} {for (i in a) if (index($0, i)) print $1}' key source
它检查 key 中的每个条目是否是源的子字符串,但我无法动脑筋检查模式(^CNACCCAAGGCTCATT)并获取上一个。和下一行
我尝试过但无法识别的另一种方法是,zcat key | match each line against source file > output
*可能是因为我的代码变慢了,非常感谢任何替代方法
【问题讨论】:
-
我怀疑使用 perl 或 awk 的脚本是否能在效率上超过 grep。如果 grep 不够快,请考虑
ripgrep(rg),它比 grep 快很多。 -
将其重构为 Perl 可能会有所帮助,因为它允许您将哈希存储在磁盘上(查找
tie)。我不认为它会特别优雅或快速,但可能会为内存耗尽问题提供一种解决方法。 -
@tripleee 是的,模式是以“@”开头的行之后的前 16 个字符。如果你能提供一个很好的工作示例,因为我不擅长编码
-
你还能谈谈模式的分布(或者你称之为“键”)吗?假设您的字母表有五个不同的符号(TCGA 加 N)是否正确?模式是随机分布在 5^16 个可能值中还是可以概括?可能是edit 你的问题,而不是在 cmets 中隐藏细节。
标签: awk