foreach循环不返回预期结果

时间:2015-09-02 03:42:45

标签: perl loops hash

我在下面编写了一个脚本来分析来自bedtools的两种文件格式(-tab选项,-name选项),因此如果序列匹配,它可以组合标题。我遇到的问题是,如果序列匹配多个名称,它只打印一个与之对应的名称。我想知道是否有人建议如何处理这个问题。因为我想要序列和名称的位置。通过bedtools可以选择吗?

我的脚本将两个文件存储到它们自己的哈希值中然后循环,如果它们相等,则假设打印出具有相应名称的序列中的匹配项。它可以做到这一点,但如果多个序列对应于名称,它不会出错,它只是不打印它们。所以我的结论是,foreach循环在语法方面是失败的,我没有注意到某种形式。有什么建议?欢呼声。

示例数据:-name output bedtools

     >sequence_a
     AGGT
     >sequence_b
     AAAA
     >sequence_c
     CCCC
     >sequence_d
     AAAA

示例数据:-tab输出bedtools

    >1-5
    AAAA
    >10-14
    ACCT
    >15-19
    CCCC

脚本的预期输出

    >sequence_b|1-5
    AAAA
    >sequence_c|15-19
    CCCC
    >sequence_d|1-5
    AAAA

脚本

my %sequence;

open(NAMES_FILE, $ARGV[0]) or die "Cannot open the file: $!";
my $hash_key_name;
my $hash_value_name;
while (my $line = <NAMES_FILE>) {
    if ($line =~ /^>(\S+)/) {
    $hash_key_name = $1;
    }
    elsif ($line =~ /\S/) {
    chomp $line;
    $hash_value_name = $line;
    $sequence{$hash_key_name} = $hash_value_name;
    }
}


my %sequence_2;
open (POSITIONS_FILE, $ARGV[1]) or die "Cannot open the file: $!";
my $hash_key_pos;
my $hash_value_pos;
while (my $line2 = <POSITIONS_FILE>) {
    if ($line2 =~ /^>(\S+)/) {
    $hash_key_pos = $1;
    }
    elsif ($line2 =~ /\S/) {
    chomp $line2;
    $hash_value_pos = $line2;
    $sequence_2{$hash_key_pos} = $hash_value_pos;
    }
}


foreach $hash_key_pos (keys %sequence_2) {
     foreach $hash_key_name (keys %sequence) {
         if ($sequence{$hash_key_name} eq $sequence_2{$hash_key_pos}){
            print ">$hash_key_name|$hash_key_pos\n$sequence{$hash_key_name}\n"}
    }
} 

1 个答案:

答案 0 :(得分:1)

哈希会愉快地覆盖值,只保存最新值,而不会抛出错误。如果你想捕获它,你需要在覆盖它之前进行显式检查以查看散列是否有值,例如:

while (my $line = <NAMES_FILE>) {
        if ($line =~ /^>(\S+)/) {
            $hash_key_name = $1;
        }
        elsif ($line =~ /\S/) {
            chomp $line;
            $hash_value_name = $line;
            if (defined($sequence{$hash_key_name}) && $sequence{$hash_key_name} ne $hash_value_name) {
                die("multiple sequences match $hash_key_name: $sequence{$hash_key_name}, $hash_value_name");
            }
            $sequence{$hash_key_name} = $hash_value_name;
        }
}

话虽如此,如果你能提供产生你想要捕获的错误的样本数据,那将是最有帮助的。看起来上面的数据不应该包含此错误。