我有一个包含3列的文件 - >
A1 0 9 A1 4 14 A1 16 24 A1 25 54 A1 64 84 A1 74 84 A2 15 20 A2 19 50
如果col1值相等,我想检查每一行(col2和3中的值)是否已存在或介于前一行的范围之间。 期望的输出是 - >
A1 0 14 A1 16 54 A1 64 84 A2 15 50
我试过了 - >
@ARGV or die "No input file specified";
open $first, '<',$ARGV[0] or die "Unable to open input file: $!";
#open $second,'<', $ARGV[1] or die "Unable to open input file: $!";
$k=0;
while (<$first>)
{
if($k==0)
{
@cols = split /\s+/;
$p0=$cols[0];
$p1=$cols[1];
$p2=$cols[2];
$p3=$cols[2]+1;
}
else{
@new = split /\s+/;
if ($new[0] eq $p0){
if ($new[1]>$p3)
{
print join("\t", @new),"\n";
$p0=$new[0];
$p1=$new[1];
$p2=$new[2];
$p3=$new[2]+1;
}
elsif ($new[2]>=$p2)
{
print $p0,"\t",$p1,"\t",$new[2],"\n";
$p2=$new[2];
$p3=$new[2]+1;
}
else
{
$p5=1;
}
}
else
{
print join("\t", @new),"\n";
$p0=$new[0];
$p1=$new[1];
$p2=$new[2];
$p3=$new[2]+1;
}}
$k=1;
}
我得到的输出是 - &gt;
A1 0 14 A1 16 24 A1 16 54 A1 64 84 A1 64 84 A2 15 20 A2 22 50
我无法理解为什么我得到错误的输出。此外,如果有任何方法可以擦除(或覆盖)最后一行,那么这将非常容易。
答案 0 :(得分:2)
首先,如果你
,帮助你会简单得多strict
和warnings
,并声明所有变量接近首次使用my
您的代码失败的原因是您在太多条件下打印数据。例如,当您发现它无法与之前的范围A1 16 24
结合时,您输出A1 4 14
而不等待后续A1 25 54
扩展(当您正确扩展范围并打印它时)再次)。出于同样的原因输出A1 64 84
两次:首先是因为它不能与A1 25 54
合并,而且因为它已经A1 74 84
“扩展”了。最后,A2 15 20
会立即输出,因为它有一个新的第一列,即使它与下一行合并并再次输出。
只有当您发现无法再次扩展时,才需要输出范围。这种情况发生在
此代码仅在出现您需要的情况下打印输出。
use strict;
use warnings;
my @data;
while (<DATA>) {
if (not @data) {
@data = split;
next;
}
my @new = split;
if ($new[0] eq $data[0] and $new[1] <= $data[2] + 1) {
$data[2] = $new[2];
}
else {
print join("\t", @data), "\n";
@data = @new;
}
print join("\t", @data), "\n" if eof DATA;
}
__DATA__
A1 0 9
A1 4 14
A1 16 24
A1 25 54
A1 52 57
A1 59 62
A1 64 84
A1 74 84
A2 15 20
A2 19 50
<强>输出强>
A1 0 14
A1 16 57
A1 59 62
A1 64 84
A2 15 50
答案 1 :(得分:0)
您需要有一些变量描述当前累积的连续区域。对于每行输入,如果新输入是新的column1标签,或者是相同的标签但不连续,或者是文件结尾,则刷新先前累积的区域。如果它是相同的标签并且是连续的,则更新最小值和最大值。
这假定第1列和第2列已排序。
其余部分留给读者练习。