我正在尝试从@ arr3打印范围值,它们是相同的并且位于@ arr4范围之外(不包括在arr4的范围内)但是我没有得到所需的输出。请在下面的代码中建议修改以获得1,2,8,13的输出(如果有的话,不重复值)
文件1:结果
1..5
5..10
10..15
文件2:注释
3..7
9..12
14..17
代码:
#!/usr/bin/perl
open($inp1, "<result") or die "not found";
open($inp2, "<annotation") or die "not found";
my @arr3 = <$inp1>;
my @arr4 = <$inp2>;
foreach my $line1 (@arr4) {
foreach my $line2 (@arr3) {
my ($from1, $to1) = split(/\.\./, $line1);
my ($from2, $to2) = split(/\.\./, $line2);
for (my $i = $from1 ; $i <= $to1 ; $i++) {
for (my $j = $from2 ; $j <= $to2 ; $j++) {
$res = grep(/$i/, @result); #to avoid repetition
if ($i != $j && $res == 0) {
print "$i \n";
push(@result, $i);
}
}
}
}
}
答案 0 :(得分:1)
试试这个:
#!/usr/bin/perl
use strict;
open (my $inp1,"<result.txt") or die "not found";
open (my $inp2,"<annotation.txt") or die "not found";
my @result;
my @annotation;
foreach my $line2 (<$inp2>) {
my ($from2,$to2)=split(/\.\./,$line2);
@annotation = (@annotation, $from2..$to2);
}
print join(",",@annotation),"\n";
my %in_range = map {$_=> 1} @annotation;
foreach my $line1 (<$inp1>) {
my ($from1,$to1)=split(/\.\./,$line1);
@result = (@result, $from1..$to1);
}
print join(",",@result),"\n";
my %tmp_hash = map {$_=> 1} @result;
my @unique = sort {$a <=> $b} keys %tmp_hash;
print join(",",@unique),"\n";
my @out_of_range = grep {!$in_range{$_}} @unique;
print join(",",@out_of_range),"\n";
print
语句当然是临时的,以帮助显示运行此命令时发生的情况。基本思路是使用一个哈希来消除“结果”中的重复数字,另一个哈希表示哪些是在“注释”中。
如果您使用了模式匹配而不是split
,那么我认为如果您输入的文件中包含一个数字,则忽略额外的输入行会更容易一些您需要跳过的“额外”行很少。
答案 1 :(得分:1)
如果文件内容在您的控制之下,您可以使用eval
进行解析。另一方面,如果可能存在您指定的内容,则以下内容使用起来很危险。
#!/usr/bin/perl
use strict;
use warnings;
use autodie;
use Data::Dumper;
open my $inc, '<', 'result';
open my $exc, '<', 'annotation';
my (%include, %exclude, @result);
while (<$inc>) { $include{$_} = 1 for eval $_ }
while (<$exc>) { $exclude{$_} = 1 for eval $_ }
for (sort {$a <=> $b} keys %include) {
push @result, $_ unless $exclude{$_}
}
print Dumper \@result;
返回:
$VAR1 = [ 1, 2, 8, 13 ];
答案 2 :(得分:0)
您需要的唯一主要工具是%seen
use strict;
use warnings;
use autodie;
my %seen;
open my $fh_fltr, '<', \ "3..7\n9..12\n14..17\n";
while (<$fh_fltr>) {
my ($from, $to) = split /\.{2}/;
$seen{$_}++ for $from .. $to;
}
my @result;
open my $fh_src, '<', \ "1..5\n5..10\n10..15\n";
while (<$fh_src>) {
my ($from, $to) = split /\.{2}/;
push @result, $_ for grep {!$seen{$_}++} $from .. $to;
}
print "@result\n";
样式哈希
以下打开文件句柄到字符串引用,但显然可以用适当的文件名替换它们:
1 2 8 13
输出:
{{1}}