我正在尝试执行以下操作
$ grep ">" file.fasta > output.txt
但是当输入的 fasta 文件很大时需要很长时间。
输入文件如下所示:
>seq1
ATCGGTTA
>seq2
ATGGGGGG
有更快的选择吗?
手工制作的状态机。如果您只希望在行首接受“>”,则需要多一个状态。如果您还需要识别“\r”,则需要更多的状态。
#include <stdio.h>
int main(void)
{
int state,ch;
for(state=0; (ch=getc(stdin)) != EOF; ) {
switch(state) {
case 0: /* start */
if (ch == '>') state = 1;
else break;
case 1: /* echo */
fputc(ch,stdout);
if (ch == '\n') state = 0;
break;
}
}
if (state==1) fputc('\n',stdout);
return 0;
}
如果您想要真正的速度,您可以将 fgetc() 和 fputc() 替换为它们的宏等价物 getc() 和 putc()。(但我认为像这样的琐碎程序无论如何都会受到 I/O 限制)
对所有这些使用 time 命令
$> time grep ">" file.fasta > output.txt
$> time egrep ">" file.fasta > output.txt
$> time awk '/^>/{print $0}' file.fasta > output.txt -- If ">' is first letter
如果您看到输出..它们几乎相同。
在我看来,如果数据是列格式的,那么使用awk进行搜索。
对于大文件,使用GNU parallelgrep
可以实现最快的速度。可以在此处找到使用and的示例。parallel
grep
出于您的目的,您可能想尝试:
cat file.fasta | parallel -j 4 --pipe --block 10M grep "^\>" > output.txt
以上将使用四个核心,并将 10 MB 块解析为grep
. 块大小是可选的,但我发现在我的系统上使用 10 MB 块大小要快得多。YRMV。
高温高压
Ack 是 grep 在代码中查找字符串/正则表达式的一个很好的替代方法: