Perl哈希和if-else条件语句

时间:2014-02-27 10:54:52

标签: perl hash

有人可以帮忙吗?我看不出我出错的地方 -

我正在尝试为输入文件中的相同值创建包含不同键的两个哈希,以便选择大于或等于2的所有键值对并将其打印到单独的文件中。

输入文件,其中第一列是ID号,第二列是ID名,第三列是表达式值。 输入文件(input.txt):

ENSG00000251791 SCARNA6 2.5
ENSG00000238862 SNORD19B 6.3
ENSG00000238527 SNORD112 -3

我想选择表达式大于或等于2的ID号和名称,然后将它们打印到单独的文件中,如下所示:

ENSG00000251791 SCARNA6 2.5
ENSG00000238862 SNORD19B 6.3

我已经简化了一个肯定有效的先前脚本(感谢M42),因为我将拥有非常大的文件,需要节省空间。

以下是代码:

use strict;
use warnings;

my $input = 'input.txt';                
open my $input_file_handle, '<', $input or die $!;

while (<$input_file_handle>) {
  chomp($_);
  my @id = split(/\s+/);
  my %id1;
  my %id2;

  my $id1{$id[0]} = $id[1];
  my $id2{$id[0]} = $id[2];
  foreach (keys%id1) {
    print $_,"\t", $id1{$_}, "\t", $id2{$_};
  }
}

foreach (keys%id1) {
  print "$_ ";
  if ($id1{$_} >= 2) {
    print "$id1{$_}";
  } else {
    print "N/A";
  }
}

我不断要求@id和%id的显式包名错误消息。我不确定我哪里出错了。如果有人有任何建议或评论,并且解释很棒。

由于 哈丽特

2 个答案:

答案 0 :(得分:1)

use strict;
use warnings;

my $input = 'input.txt';                
open my $input_file_handle, '<', $input or die $!;

my %hash;
while (<$input_file_handle>) {
  chomp;
  my ($k, @id) = split /\s+/;
  $hash{$k} = \@id;
}

for my $k (sort keys %hash) {
  my $id = $hash{$k};
  if ($id->[1] >=2) {
    print "@$id\n";
  }
}

答案 1 :(得分:1)

您收到“显式包”警告的原因是您在错误的范围内声明变量:

while (<$input_file_handle>) {
    ...
    my @id ...
}  # end of block that @id is in -> end of scope

   # @id is out of scope here

因此,如果您希望错误消失,请在while循环之外声明变量。但是,您尝试的解决方案并不是很好。首先,你根本不需要存储任何值,如果你想要做的就是检查第3列是否> = 2.其次,你不需要两个哈希来存储值,你只需要使用一个值。第三,如果您只想重新打印原始行,那么存储split的值是没有意义的。这就是您真正需要的功能:

while (<>) {
    my ($num, $name, $val) = split;
    if ($val >= 2) {
        print;
    }
}

此处的所有值都存储在临时变量中,这些变量在每次循环迭代结束时都超出范围。

你会这样称呼:

perl script.pl input.txt > output.txt

这也是一个相当简单的单行:

perl -ane 'if ($F[2] >= 2) { print }' input.txt > output.txt
相关问题