有人可以帮忙吗?我看不出我出错的地方 -
我正在尝试为输入文件中的相同值创建包含不同键的两个哈希,以便选择大于或等于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的显式包名错误消息。我不确定我哪里出错了。如果有人有任何建议或评论,并且解释很棒。
由于 哈丽特
答案 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