Perl 检测数据文件中的开始和停止位置重叠并将其分离
我正在使用的这个脚本旨在浏览一个文件并检测重叠的时刻,所有重叠的位置都被放入新文件中 第2列可以被视为开始位置,第2列可以被视为停止位置,因此在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 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;
}