![如何打印文件名和fasta序列总数?](https://linux22.com/image/195328/%E5%A6%82%E4%BD%95%E6%89%93%E5%8D%B0%E6%96%87%E4%BB%B6%E5%90%8D%E5%92%8Cfasta%E5%BA%8F%E5%88%97%E6%80%BB%E6%95%B0%EF%BC%9F.png)
我有一个 fasta 文件,即 test.fasta、pas.fasta、cel.fasta 如下所示
test.fasta
>tile
ATGTC
>259
TGAT
pas.fasta
>ta
ATGCT
cel.fasta
>787
TGTAG
>yog
TGTAT
>In
NNTAG
我需要打印文件名和 fasta 序列总数,如下所示,
test,2
pas,1
cel,3
我使用了以下命令但未能达到我的目的
grep ">" test.fasta | wc -l && ls test.fasta
请帮助我做同样的事情。
提前致谢。
答案1
这就是(to ount)-c
选项的用途:grep
c
$ grep -ce '^>' -- *.fasta
cel.fasta:3
pas.fasta:1
test.fasta:2
请注意,如果只有一个匹配文件,则不会打印文件名。某些grep
实现可以-H
选择强制始终打印文件名:
$ grep -Hce '^>' -- *.fasta
cel.fasta:3
要获得确切的预期输出,您只需替换.fasta:
为,
:
$ grep -Hce '^>' -- *.fasta | sed 's/\.fasta:/,/'
cel,3
pas,1
test,2
(这里假设您的文件名不包含其他出现的情况,.fasta:
例如my.fasta:foo.fasta
; 当然,如果输出采用 CSV 格式,文件名中的换行符或,
或字符以及潜在的空白字符也会成为问题)"
答案2
使用 GNU awk 来表示ENDFILE
和gensub()
:
$ awk '/^>/{c++} ENDFILE{print gensub(/\.[^.]*$/,",",1,FILENAME) c+0; c=0}' *.fasta
cel,3
pas,1
test,2
无论存在 1 个还是多个输入文件(只要它小于 shell args 限制),并且无论文件名中存在哪些字符,只要不存在=
(当 awk 可以时,在某些情况下),上述内容都将起作用,将其视为变量赋值 - 如果会发生这种情况,请参阅https://www.gnu.org/software/gawk/manual/gawk.html#Other-Arguments了解如何处理)。
您可以对任何 awk 执行相同的操作:
$ awk '/^>/{c[FILENAME]++} END{for (i=1; i<ARGC; i++) {f=ARGV[i]; sub(/\.[^.]*$/,",",f); print f c[ARGV[i]]+0} }' *.fasta
cel,3
pas,1
test,2
答案3
使用 Raku(以前称为 Perl_6)
~$ raku -e 'for dir(test => / \.fasta $/ ) -> $fh { put ($fh, $_.grep(/ ^^ \> /).elems).join(",") given $fh.lines() };' > outfile.txt
#OR
~$ raku -e 'for dir(test => / \.fasta $/ ) -> $fh { put join ",", $fh, $_.grep(/ ^^ \> /).elems given $fh.lines() };' > outfile.txt
输入示例(密码):
~$ ls *.fasta
cel.fasta pas.fasta test.fasta
示例输出:
cel.fasta,3
pas.fasta,1
test.fasta,2
该解决方案使用 Raku,Perl 编程语言家族的成员。上面的代码依赖于 Raku 的dir()
和grep()
例程,因此在经典 shell 介导的文件通配不存在或受到限制的平台上可能很有用(请参阅 SO 讨论这里)。
简而言之,raku
使用-e
选项调用,它告诉 Raku 的编译器 (Rakudo) 编译并执行给定的单行程序。dir()
使用关键字调用该方法for
,该关键字告诉 Raku 循环使用过滤器获得的文件名值test => / \.fasta $/
。由此找到的文件名被单独加载到$fh
变量中并在{…}
块中进行分析。
在块内部,从右到左读取,lines
是从$fh
filehandle 变量中提取的,该变量会自动加载到$_
topic 变量中。这些行(现在保存在 中$_
)grep
通过 -ped 来查找具有^^
start-of-line的行>
,表示新序列的开始fasta
。这样找到的行使用 进行计数elems
,并且$fh
和 计数使用逗号进行join
分隔,
并使用 逐行返回put
。
OP最初要求返回“文件名”,因此从技术上讲,上面的代码就足够了。然而,因为$fh
是IO::Path
对象,所以删除扩展名很容易.fasta
:只需附加extension
例程即可$fh
识别.fasta
扩展名,然后将其替换为空(""
):
~$ raku -e 'for dir(test => / \.fasta $/ ) -> $fh { put ($fh.extension(""), $_.grep(/ ^^ \> /).elems).join(",") given $fh.lines() };'
cel,3
pas,1
test,2
https://docs.raku.org/routine/dir
https://docs.raku.org/routine/grep
https://docs.raku.org/routine/extension
https://raku.org