更快地替代Unix Grep

更快地替代Unix Grep,unix,grep,Unix,Grep,我试着做以下几点 $ grep ">" file.fasta > output.txt 但是当一个文件的输入太大时,它会花费很长时间 输入文件如下所示: >seq1 ATCGGTTA >seq2 ATGGGGGG 有更快的替代方案吗?使用time命令处理所有这些问题 $> time grep ">" file.fasta > output.txt $> time egrep ">" file.fasta > output.txt

我试着做以下几点

$ grep ">" file.fasta > output.txt
但是当一个文件的输入太大时,它会花费很长时间

输入文件如下所示:

>seq1
ATCGGTTA
>seq2
ATGGGGGG

有更快的替代方案吗?

使用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进行搜索

手工构建的状态机。如果您只希望在行的开头接受“>”,则还需要一个状态。如果您也需要识别'\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;
}
#包括
内部主(空)
{
int状态,ch;
for(state=0;(ch=getc(stdin))!=EOF;){
开关(状态){
案例0:/*开始*/
如果(ch='>')状态=1;
否则就断了;
案例1:/*回声*/
fputc(ch,stdout);
如果(ch=='\n')状态=0;
打破
}
}
如果(state==1)fputc('\n',stdout);
返回0;
}

如果您想要真正的速度,可以将fgetc()和fputc()替换为它们的宏等价物getc()和putc()。(但我认为像这样的琐碎程序无论如何都会受到I/O的限制)

对于大文件,最快的
grep
可以用。可以找到使用
parallel
grep
的示例

出于您的目的,您可以尝试:

cat file.fasta | parallel -j 4 --pipe --block 10M grep "^\>" > output.txt
上面的代码将使用四个内核,并将10MB的块解析为
grep
。块大小是可选的,但我发现在我的系统上使用10 MB块大小要快得多。YRMV


HTH

Ack是grep在代码中查找string/regex的一个很好的替代方法:


在I/O主导的大计划中,这可能不会有太大的区别,但如果你想要的话,你可以尝试将匹配锚定到每行的第一个字符。@Thilo我也想到了这一点,但对我来说差异只有10%左右。构建一个基于状态机的识别器?(大约需要4个州)