1

我正在尝试通过使用第二个文件来过滤文件(试图找到最佳的爆炸命中)。我要过滤的文件如下所示:

conserved1      chr22   100.00  92      0       0       1       92      19679676                        19679767        2e-44    182
.....................

我正在使用的第二个文件(这是我脚本中的第一个输入)是这样的:

conserved1      92
conserved2      76
.....................

(第一列是我的“项目”的名称,与前一个文件的第一列完全相同,第二列是大小)。

我将第二个文件存储在哈希中,以便将第一个文件与保留元素的大小连接起来,并仅过滤大小(第 4 列)为大小(来自第 2 个文件)的 70% 的行。

我为此目的编写了这个脚本,它可以工作,但它会多次打印每个选定的行。我怎样才能解决这个问题?

my $size_file = $ARGV[0];
my $alignment_file = $ARGV[1];

open my $con_info, $size_file or die "Could not open $size_file: $!";

my %hash;
while (<$con_info>)
{
chomp;
my ($key, $val) = split /\t/;
$hash{$key} .= exists $hash{$key} ? "$val" : $val;
}
#print "# %hash\n", Dump \%hash;
#print %hash;
#print "@{[%hash]}";

close $con_info;

open my $al_info, $alignment_file or die "Could not open $alignment_file: $!";

while (my $line = <$al_info>)  {
    chomp;
    my@data = split('\t', $line);
    my $con_name = $data[0];
    my $evalue = $data[10];
    my $percent = $data[2];
    my $length = $data[3];
   # print $con_name. "\n";

foreach my $key (keys %hash) {
    if ($key  == $con_name) {
       #print "key: $key, value: $hash{$key}\n";
            if ($evalue <= 1e-4 && $length >= 0.70 * $hash{$key}) {
                    print $line;
            }

    }
   }
}

输出应该是第一个文件(位于第一个代码框的文件),但行数较少,即通过最后一个 if 条件的行。非常感谢您的帮助!!!

4

1 回答 1

2
if ($key  == $con_name)

应该

if ($key eq $con_name)

因为这应该是字符串比较。

而且您实际上并不需要foreach循环,只需选择一个特定的键:

while (my $line = <$al_info>)  {

    chomp($line);
    my @data = split('\t', $line);
    # my $con_name = $data[0];
    # my $percent = $data[2];
    # my $length = $data[3];
    # my $evalue = $data[10];
    my ($con_name, $percent, $length, $evalue) = @data[0,2,3,10];

   # print $con_name. "\n"; 
   if ($evalue <= 1e-4 && $length >= 0.70 * $hash{$con_name}) {
            print $line;
   }
}
于 2013-09-12T19:30:49.870 回答