Perl:foreach中重新启动导致的冗余?

Perl:foreach中重新启动导致的冗余?,perl,loops,search,foreach,Perl,Loops,Search,Foreach,我试图在2000多个子目录中的每一个子目录中从“pairsAngles.txt”grep字符串“Distance:”;子目录的名称从csv文件中获取。但出于某种原因,foreach()会从每个循环的开始处重新启动。因此,输出如下所示: 显然所有的距离都应该在一列中 我不确定是哪一步导致了问题。 代码如下: #!/usr/bin/perl -w use strict; use warnings; use File::Find; use List::MoreUtils qw(uniq); use C

我试图在2000多个子目录中的每一个子目录中从“pairsAngles.txt”grep字符串“Distance:”;子目录的名称从csv文件中获取。但出于某种原因,foreach()会从每个循环的开始处重新启动。因此,输出如下所示: 显然所有的距离都应该在一列中

我不确定是哪一步导致了问题。 代码如下:

#!/usr/bin/perl -w
use strict;
use warnings;
use File::Find;
use List::MoreUtils qw(uniq);
use Cwd qw(cwd);
use Text::CSV_XS;
use Data::Dumper;

my @pairs=qw();
my @result=();

my $in;
my $out;
my $pairs;
my $dist = "";
my $dir = "/home/avabelieve/aaPROJECT/helicalPair_ax/selectedPairs/renumberedPdb/clusterPairs-1.25-12-05_windows.12.resle3.2A.RMSD1.3/oligomerAngle";

my $cluster = "clst1.csv";
open ($in, $cluster) || die "cannot open \"$cluster\": $!";

my $cU = "clst1Updated.csv";
open ($out, ">$cU") || die "cannot open '$cU' $!";

my $csv = Text::CSV_XS->new ({ binary => 1, auto_diag => 1, eol => $/ });

while (my $c1 = <$in>) {    
    chomp $c1;
    push @pairs, $c1;

    foreach $c1 (uniq @pairs) {
        find (\&Matches, "$dir/$c1");
        sub Matches {
            open ($pairs, "pairsAngles.txt") or die "$!";

            while (my $dist = <$pairs>) {

                if ($dist =~ m/Distance: /) {                    

                    chomp $dist;
                    push (@result, "$dist\n");
                    @result = split "\t", $dist;
                }               

            } 
        }
    }
    chdir "..";

    if (not $csv->eof) {
        $csv->error_diag();
    }
    $csv->say ($out, [uniq @pairs, @result]);
}
close $out or die "$!";
#/usr/bin/perl-w
严格使用;
使用警告;
使用File::Find;
使用列表::MoreUtils qw(uniq);
使用Cwd qw(Cwd);
使用Text::csvxs;
使用数据::转储程序;
我的@pairs=qw();
我的@result=();
我的美元;
我的美元用完了;
我的$pairs;
我的$dist=“”;
my$dir=“/home/avalbelise/aaPROJECT/helicalPair\u ax/selectedPairs/renumberedPdb/clusterPairs-1.25-12-05\u windows.12.resle3.2A.RMSD1.3/oligomerAngle”;
my$cluster=“clst1.csv”;
打开($in$cluster)| | die“无法打开\“$cluster\”:$!”;
my$cU=“clst1Updated.csv”;
打开($out,“>cU”)| |骰子“无法打开“$cU”$!”;
我的$csv=Text::csv_XS->new({binary=>1,auto_diag=>1,eol=>$/});
而(我的$c1=){
咀嚼$c1;
按@对,$c1;
每件$c1(uniq@双){
查找(\&匹配,“$dir/$c1”);
子匹配{
打开($pairs,“pairsAngles.txt”)或死亡“$!”;
while(my$dist=){
如果($dist=~m/距离:/){
chomp$dist;
推送(@result,“$dist\n”);
@结果=拆分“\t”,$dist;
}               
} 
}
}
chdir“.”;
如果(不是$csv->eof){
$csv->错误诊断();
}
$csv->say($out,[uniq@pairs,@result]);
}
关闭$out或死“$!”;

有两个地方让我感到困惑

(1) 使用
推送@pairs,$c1
@pairs
添加一行输入。但每次都要处理所有(唯一)对。因此,您的代码首先重新处理所有以前处理过的对,然后添加这些对。这是有意的吗?似乎这样你会得到重复的结果。相反,您可以收集对,删除重复项,然后进行处理

my @pairs = uniq <$in>;  # chomp if needed, chomp(@pairs)
foreach $c1 (@pairs) { ... }

同样,这是有意的吗?

while循环将添加到
@对的列表中

while (my $c1 = <$in>) {    
    chomp $c1;
    push @pairs, $c1;
由于
foreach
循环位于
while
循环内,因此每次将一对添加到
@pairs
中时,
foreach
循环将从头开始在不断增长的
@pairs
上重复

要避免这种情况,请完成构建
@对
,然后在其上循环

while (my $c1 = <$in>) {    
    chomp $c1;
    push @pairs, $c1;
}

foreach $c1 (uniq @pairs) {
    find (\&Matches, "$dir/$c1");
    ...
}

您说过“foreach()从每个循环的开始处重新启动”。。。什么的开始?哪个循环的开始?我想我知道你的意思,但是你能澄清一下吗?csv文件的开头,它包含了所有的子目录名。很好。这绝对不是故意的。。。我只是想从输入csv文件中获取所有子目录名(@pairs),然后执行grep。实际上,这里不需要“uniq”,因为所有子文件夹名称都是唯一的;然而,我一直收到重复的结果…啊,那就放下
uniq
,更好了。请注意,您可能也不需要咀嚼(取决于处理过程)。第二点也是有效的——代码确实改变了
@result
两次,而且方式相互矛盾。其中一个是不需要的。第二个总是覆盖整个
@结果
。非常感谢zdim!我希望系统允许我也给你一个绿色的复选标记…@AvaXue好吧,非常感谢你这么说——但别担心,你接受了一个,这就是它应该的:)。请注意,您可以像任何其他用户一样“投票”任何和所有答案,请参阅。“绿色支票”业务是您作为问题作者的额外特权。我不是特别问你做了什么(不要告诉我!),也绝对不是建议什么,只是让你知道万一你没有。再次感谢您的评论:)。while循环的更改实际上不起作用。。。而且,现在输出返回到一行。。。见我的第三个问题:
foreach $c1 (uniq @pairs) {
    find (\&Matches, "$dir/$c1");
while (my $c1 = <$in>) {    
    chomp $c1;
    push @pairs, $c1;
}

foreach $c1 (uniq @pairs) {
    find (\&Matches, "$dir/$c1");
    ...
}
my @pairs = <$in>;
chomp @pairs;