专栏名称: 生信媛
生信媛,从1人分享,到8人同行。坚持分享生信入门方法与课程,持续记录生信相关的分析pipeline, python和R在生物信息学中的利用。内容涵盖服务器使用、基因组转录组分析以及群体遗传。
目录
相关文章推荐
51好读  ›  专栏  ›  生信媛

如何用C语言实现单行数据转fasta

生信媛  · 公众号  · 生物  · 2020-03-19 07:00

正文

请到「今天看啥」查看全文


之前立了一个学习C语言的flag, 这一次我要真正学会C语言 ,虽然很久没有写相关的推送,但是一直也在默默学习。

昨天看了 Linux的日常·单行数据转fasta后 ,因为需求简单,想着也不复杂,于是我就试试了用C语言实现这个小功能。

任务是将下面格式文本

名称1 tab分隔 名称2 tab分隔 名称3 tab分隔 序列 tab分隔 null

转成如下的格式

>名称1|名称2|名称3
序列

我写的代码总共就36行。

  1. #include

  2. #include

  3. #include "klib/kseq.h"


  4. KSTREAM_INIT(gzFile, gzread, 16384)


  5. typedef struct {

  6. char name[256];

  7. char comment1[256];

  8. char comment2[2048];

  9. char seq[2048];

  10. } Fasta ;


  11. int main(int argc, char const *argv[])

  12. {

  13. gzFile fp;

  14. kstream_t *ks;

  15. kstring_t str = {0,0,0};

  16. if ( argc == 1){

  17. fprintf(stderr, "Usage: %s ", argv[0]);

  18. }


  19. fp = gzopen(argv[1], "r");

  20. ks = ks_init(fp);

  21. Fasta *fa = (Fasta *)malloc(sizeof(Fasta));

  22. while ( ks_getuntil(ks, '\n', &str, 0) >= 0){

  23. sscanf(str.s, "%[^\t]\t%[^\t]\t%[^\t]\t%[^\t]\t", fa->name, fa->comment1, fa->comment2, fa->seq);

  24. printf(">%s %s %s\n%s\n", fa->name, fa->comment1, fa->comment2, fa->seq);

  25. }


  26. ks_destroy (ks);

  27. gzclose(fp);

  28. free(str.s);

  29. free(fa);

  30. return 0;

  31. }

最开始的三行用于导入头文件,类似于R语言的 library ,Python里的 import 。着重介绍的是 kseq . h , 这是attractivechaos写的klib库中的一个头文件,一个非常高效文本读取库,几乎在所有李恒大神写的工具里都出现了klib库。

代码的主要部分就是调用了kseq.h读取文本,所以请移步到 C语言-使用klib/kseq.h高效读取行

我增加的内容为定义了一个结构体 Fasta , 将 sscanf 解析的数据存放到对应的位置。

  1. sscanf(str.s, "%[^\t]\t%[^\t]\t%[^\t]\t%[^\t]\t", fa->name, fa->comment1, fa->comment2, fa->seq);

输出用的是 printf 函数

  1. printf(">%s %s %s\n%s\n", fa->name, fa->comment1, fa->comment2, fa->seq);

之后通过下面的方法进行编译

  1. gcc -o one2fa one2fa.c -lz

之后就当做普通的命令行一样使用

  1. ./one2fa temp


最后说两句:这里用C语言不是最优解,这是练习而已,这类文本转换建议用sed/python/perl/awk,。当然如果数据量非常大,我觉得还是可以考虑下C/C++的、


推荐阅读

C语言实战课-写一个fastq转fasta的程序

C语言实战-让程序能够处理压缩文件







请到「今天看啥」查看全文