【问题标题】:Perl hash and if-else conditional statementPerl 哈希和 if-else 条件语句
【发布时间】:2014-03-30 18:06:43
【问题描述】:

有人可以帮忙吗?我看不出哪里出错了-

我正在尝试为输入文件中的相同值创建两个包含不同键的哈希,以便选择所有大于或等于 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 的需要明确的包名称错误消息。我不确定我哪里出错了。如果有人有任何建议或解释,那就太好了。

谢谢 哈丽特

【问题讨论】:

    标签: perl hash


    【解决方案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
    

    【讨论】:

      【解决方案2】:
      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";
        }
      }
      

      【讨论】:

      • 有没有办法同时保留列 ID 号和名称?我知道它过于复杂,但我需要两个 ID。除此之外,它的效果很好!
      • 我收到更多错误消息:在 test.pl 第 18 行, 第 8 行中使用数字 ge (>=) 中未初始化的值。我已经尝试过我的 @id , $id 和注释掉使用命令但没有输出
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-30
      • 1970-01-01
      • 2023-02-06
      • 2019-01-24
      • 1970-01-01
      相关资源
      最近更新 更多