我有两个数据集:'数据1'和'数据2'。你能帮我找一下'数据1'中posi的每个值,'数据2'中的位置,其中posi位于Star_posi和end_posi之间。
Num posi
1 2
2 14
3 18
4 19
... ...
Num Star_posi End_posi
1 1 10
2 3 15
3 17 21
4 23 34
... ... ...
我想识别数据2中的行,其中数据1中的值包含在数据2中的行的范围内。我在下面创建了脚本,但是我没有达到目标。
#!/usr/bin/perl -w
use strict;
use warnings;
use Data:ump qw(dump);
#Sort the position**************
my (@posi1, $Num2, @Num2, @Num1);
open(POS1,"<posi.txt");
@posi1=<POS1>;
@Num1=@posi1;
open(LIST,">list.txt"); {
@Num2= sort {$a <=> $b} @Num1;
$Num2 = join( '', @Num2);
print $Num2;
print LIST $Num2."\n";
}
close(LIST);
如果你能给出一些指示,我将不胜感激。
答案 0 :(得分:3)
你的代码很乱。此外,它不会以任何方式解决您的问题。
您要做的是split
来自while
循环中文件的行,并将它们存储在散列中。获得这些值后,您可以轻松地将它们与<
和>
运算符进行比较,以查看它们落入的范围。
use strict;
use warnings;
use autodie;
my (%data1,%data2);
open my $in, '<', 'data1.txt';
while (<$in>) {
next unless /^\s*\d/;
my ($num, $posi) = split;
$data1{$num} = $posi;
}
open $in, '<', 'data2.txt';
while (<$in>) {
next unless /^\s*\d/;
my ($num, $star, $end) = split;
$data2{$num}{'star'} = $star;
$data2{$num}{'end'} = $end;
}
close $in;
请注意,我正在跳过(next
)任何不以数字开头的行,例如标题和空行以及我们在数据中不需要的其他内容。
现在,您将拥有哈希值,并可以执行您需要的测试。例如:
for my $num (keys %data1) {
my $val = $data1{$num};
for my $num2 (keys %data2) {
my $min = $data2{$num2}{'star'};
my $max = $data2{$num2}{'end'};
if ( ($val > $min) and ($val < $max) ) {
print "Data 1 at posi $val contained in Data 2 between star_posi $min and end_posi $max.\n";
last;
}
}
}
祝你好运!
答案 1 :(得分:2)
您应该查看名为Tie::RangeHash的CPAN模块,该模块用于完全此类问题。
use Tie::RangeHash;
my $hour_name = new Tie::RangeHash Type => Tie::RangeHash::TYPE_NUMBER;
$hour_name->add(' 0, 5', 'EARLY');
$hour_name->add(' 6,11', 'MORNING');
$hour_name->add('12,17', 'AFTERNOON');
$hour_name->add('18,23', 'EVENING');
# and in a loop elsewhere...
my $name = $hour_name->fetch($hour) || "UNKNOWN";