确定哪些文件至少有特定数量的行与模式匹配

Determine which files have at least a particular number of lines matching a pattern

我正在寻找一种方法来识别 FASTA 至少包含 3 个序列的文件。序列由以 >.

开头的行标识

以下是 5 个文件的示例:

文件 1

>sp1
ATTTT
>sp3
ATTGG
>sp3
ATTGAGGAGA
>sp4
AGGGGAGGACC
>sp5
AGGGGGG
>sp5
AGGGGGG

文件2

>sp1
ATTTT

文件 3

>sp1
ATTTT
>sp3
ATTGG
>sp3
ATTGAGGAGA
>sp4
AGGGGAGGACC
>sp5
AGGGGGG

文件4

>sp1
ATTTT
>sp3
ATTGG

文件5

>sp1
ATTTT
>sp3
ATTGG
>sp3
ATTGAGGAGA
>sp4
AGGGGAGGACC
>sp5
AGGGGGG

我想要输出:

file1
file3
file5 

因为这些文件至少包含三个序列。我可以用 ls 做这个吗?

这应该可以完成工作:

grep -Hc '^>' * 2>/dev/null | awk -F':' ' > 3 {print }'

工作原理:

  • grep -Hc '>' * 计算在所有内容中都有“>”的行数 ('*')
  • 2>/dev/null 抑制错误消息,因为 grep-ing on * 也匹配目录并导致错误
  • 对于每个匹配项,grep 输出 fileName:n,n 是找到的匹配项数
  • 然后 Awk 被教导读取每一行的第二个字段('$2'),如果它大于 3( > 3 部分),则显示文件名,即第一个字段该行(即 </code>)</li> <li><code>-F':' 部分指示 awk 什么是字段分隔符

使用 GNU awk:

$ awk '(FNR==1){c=3}/^>/{c--}!c{print FILENAME; nextfile}' * 

这不会处理整个文件,但足以确定 fasta-file 是否有 3 个或更多序列:

  • 每次我们输入一个新文件时,file-record 数字 FNR 都会重置为 1。如果发生这种情况,我们会将计数器 c 重置为 3。
  • 每次我们看到以 > 开头的行时,我们都会递减计数器
  • 如果我们遇到 3 个序列(被 c==0 识别),我们打印 FILENAME 并移动到下一个文件。

这是一个 Perl one-liner,原因有二:这个问题很有趣;这个问题促使我学习更多关于 Perl 的知识!

perl -ne '++$count if /^>/; $count=0, close ARGV, print "$ARGV\n" if $count==3' *
  • perl -ne:不打印处理过的行; 运行下面的代码
  • ++$count if /^>/; - 计算以 > 开头的行数。 $count 开始未定义,Perl 的 ++ 将其视为 0.
  • $count=0 ... close ... print ... if $count==3:一旦我们看到以 > 开头的第三行,请重置 $count 并执行 closeprint
    • close ARGV: 不再处理当前文件中的任何行
    • print "$ARGV\n":打印我们刚刚处理完的文件名。 $ARGV 是当前文件的名称,在处理下一行之前不会重置。请参阅 perlop's I/O operators section 中的 "Perl-like pseudo code"。

编辑 顺便说一下,Perl 实际上在 BioPerl and other modules. See, e.g., https://metacpan.org/search?q=FASTA 中有对 FASTA 的库支持。