我的文件有多个列,其中包含以下格式的文本“number / number:zero,number_of_interest”。示例:“1/1:0,13”。
如果任何列中感兴趣的数量小于20,我需要删除行。 我更喜欢使用egrep而不是读取文件,但不确定如何在单个语句中评估每列感兴趣的数量。
我还删除了包含SVLEN = -1或SVLEN = -2的行,它似乎与egrep一起运行良好:
$cmd2 = `egrep -v 'SVLEN=-1;|SVLEN=-2;' $my_vcf > $my_new_vcf`; print $cmd1;
我尝试过以下但是没有用:
my $cmd2 = `egrep -v 'SVLEN=-1;|SVLEN=-2;|(\,(\d+) < 20)' $my_vcf > $my_new_vcf`; print $cmd2;
谢谢。
答案 0 :(得分:2)
egrep
是用于此目的的错误工具,因为它无法在其正则表达式中进行数学运算。
因为您已经有了Perl脚本,所以最好使用Perl命令来实现目标。
不幸的是,你必须逐行打开并阅读文件才能这样做,但这正是egrep
所做的。怎么还能判断这些线?
#!/usr/bin/env perl
use strict;
use warnings;
use List::Util;
sub filter_lines
{
my $in_filename = shift;
my $out_filename = shift;
open( my $fhin, '<', $in_filename ) or die "cannot open $in_filename: $!\n";
open( my $fhout, '>', $out_filename ) or die "cannot open $out_filename: $!\n";
while ( my $line = <$fhin> ) {
next if ( $line =~ /SVLEN=-1;|SVLEN=-2;/ );
if ( my @numbers_of_interest = ( $line =~ m/\d+\/\d+:0,(\d+)/g ) ) {
next unless List::Util::min(@numbers_of_interest) < 20;
}
print $fhout $line;
}
close($fhin);
close($fhout);
}
filter_lines( $my_vcf, $my_new_vcf );
因为我没有确切的输入行,@numbers_of_interest
的模式可能有点不准确,需要改进。如果此代码变慢,还有很大的优化空间。