Perl 检测数据文件中的开始和停止位置重叠并将其分离

Perl 检测数据文件中的开始和停止位置重叠并将其分离,perl,Perl,我正在使用的这个脚本旨在浏览一个文件并检测重叠的时刻,所有重叠的位置都被放入新文件中 第2列可以被视为开始位置,第2列可以被视为停止位置,因此在 2 6 10 5 2 9 13 5 3 8 9 5 前两条线将重叠,因为第二条线从9开始,第一条线在10结束,因此它们将在9-10位置重叠。 但是,第三行没有重叠,因为第一列中的数字是3,而不是2,这是必要的标准 现在您了解了重叠的含义 ARGV[0]中的输入是一个类似的文件 9 9000000 14100000 23 9 900000

我正在使用的这个脚本旨在浏览一个文件并检测重叠的时刻,所有重叠的位置都被放入新文件中

第2列可以被视为开始位置,第2列可以被视为停止位置,因此在

2 6 10 5
2 9 13 5
3 8 9 5
前两条线将重叠,因为第二条线从9开始,第一条线在10结束,因此它们将在9-10位置重叠。 但是,第三行没有重叠,因为第一列中的数字是3,而不是2,这是必要的标准

现在您了解了重叠的含义

ARGV[0]中的输入是一个类似的文件

9   9000000 14100000    23
9   9000000 32800000    4
9   9000000 40200000    6
9   9000000 42400000    5
9   89600000    116700000   28
9   89600000    129300000   8
9   89600000    140273252   52
S   0   24900000    2
S   0   24900000    22
S   0   37500000    2
S   40000000 45000000 7
S   42500000 47000000 9
给定此文件,ARGV[1]最终将在其中包含

9   9000000 14100000    23
9   89600000    116700000   28
S   0   24900000    2
S   40000000 45000000 7
这个(稍后我将调用z.txt)将被传递到标准输出

9   9000000 32800000    4
9   9000000 40200000    6
9   9000000 42400000    5
9   89600000    129300000   8
9   89600000    140273252   52
S   0   24900000    22
S   0   37500000    2
S   42500000 47000000 9
ARGV[3]本质上是一个wc-l#文件| awk'{print$1}' ARGV[0]所在的文件的

这是密码

#!/usr/bin/perl
# ARGV[0] is the name of the file which data will be read from(may have overlaps)
# ARGV[1] is the name of the file which will be produced that will have no overlaps
# ARGV[2] is the name of a directory
# ARGV[3] is the number of lines that ARGV[0] will contain
#The purpose of this script is to look through the data file and if there are overlaps then another layer is created
use warnings;
#use strict;

#Here I am just trying to open up my file in order to read from it
my $file = "./$ARGV[0]";
my @lines = do {
    open my $fh, '<', $file or die "Can't open $file -- $!";
    <$fh>;
};

#Here I am assignning a secon file that will contain the overlaps
my $file2 = "./$ARGV[2]/$ARGV[1]";
open(my $fh, ">", "$file2")
        or die "Can't open > $file2: $!";

# For each element compare all following ones, but cut out
# as soon as there's no overlap since data is sorted
my $i = 0;
while ($i < $ARGV[3]) {
        my @ref_fields = split('\s+', $lines[$i]);
#This line is printed to the file handle because it shouldn't have any overlaps so everyline in this file will not overlap with any other
        print $fh "$ref_fields[0]", "\t", $ref_fields[1], "\t", $ref_fields[2], "\t", $ref_fields[3], "\n";
#The script then looks at the lines following the line just looked at
        for my $j ($i+1..$ARGV[3]) {
                my @curr_fields = split /\s+/, $lines[$j];
#if the line does overlap then print it to standard output
                if ( $ref_fields[2] > $curr_fields[1] ) {
                        print $curr_fields[0], "\t", $curr_fields[1], "\t", $curr_fields[2], "\t", $curr_fields[3], "\n";
                }
                else {
#if it doesn't, since all the file is sorted the overlaps are done with
                        $i=$j;
                        last;
                }
        }
        $i++;
}
以及它应该打印的标准输出

9   9000000 40200000    6
9   9000000 42400000    5
9   89600000    140273252   52
S   0   37500000    2

首先,这个赋值有一个错误:$i=$j;这样,当发生重叠时,您将超出一条输入线。 其次,内部循环列表应该是($i+1..$ARGV[3]-1),而不是($i+1..$ARGV[3])。 第三,当文件末尾没有重叠时,需要跳过已处理的行。 否则你会一遍又一遍地听到同样的话。 可以这样做(注意$new_i):

while($i<$ARGV[3]){
...
my$new_i=$i;
对于我的$j($i+1..$ARGV[3]-1){
$new_i=$j;
...
否则{
#你不需要这个任务
#$i=$j;
最后;
}
}
$i=$new_i+1;
}

您是要求我们调试您的代码,还是有具体问题?是的,是调试,我想知道为什么会发生这种情况“我的原始ARGV[0]大约有1300行,它以某种方式将大约6000行输出转换为标准输出”
9   9000000 40200000    6
9   9000000 42400000    5
9   89600000    140273252   52
S   0   37500000    2
while ($i < $ARGV[3]) {
...
    my $new_i=$i;
    for my $j ($i+1..$ARGV[3]-1) {
        $new_i=$j;
        ...
        else {
            # you don't need this assignment
            # $i=$j;
            last;
        }
    }
    $i=$new_i+1;
}