确定哪些文件至少有特定数量的行与模式匹配
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
并执行 close
和 print
。
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 的库支持。
我正在寻找一种方法来识别 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
并执行close
和print
。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 的库支持。