Perl: output still only one line

隐身守侯 提交于 2019-12-20 06:37:38

问题


This is the 3rd question on the same project: I was trying to grep string "Distance: " from "pairsAngles.txt" within each of over 2,000 subdirectories; the names of the subdirectories are obtained from a csv file. After passing eol => $/ to Text::CSV_XS->new AND use $csv->say, the output is still one line...

#!/usr/bin/perl -w
use strict;
use warnings;
use File::Find;
use Text::CSV_XS;

my @pairs=();
my @result=();
my $c1;
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 ($c1 = <$in>) {
    chomp $c1;
    push @pairs, $c1;
}

foreach $c1 (@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");
            }               

        } 
    }
}
chdir "..";

if (not $csv->eof) {
    $csv->error_diag();
} 

$csv->say ($out, [@pairs, @result]);
close $out or die "$!";

回答1:


I don't see how you want to combine @pairs and @result in your output, but to write out the whole array into a spreadsheet you need, per synopsis in Text::CSV_XS docs

 $csv->say ($fh, $_) for @rows;

Let us know how @pairs and @result should be paired in output for more detail.


A clarification: the written rows should have a cell for directory and another for the corresponding matching line, and we know for sure that there is exactly one such match in each file. Then

if (@pairs != @result) {
    die "Mismatching lengths: directory " . scalar(@pairs) .
        " vs matches " . scalar(@result);
}
for my $i (0..$#pairs) {
    $csv->say($out, [$pairs[$i], $result[$i]]);
} 

Please note that @pairs != @result does not guard against all possible unexpected mismatches, it is more of a hint to include stricter checking in the code. (There could be a no-match in one file but two in another and arrays would end up having the same length, for example.) A check where @result is added to would test that there was indeed exactly one match.


A note. The code at one place removes the new line with chomp but then puts it back, \n.

chomp $dist;
push (@result, "$dist\n");

The \n is not needed and then "" are not needed either -- just push @result, $dist;. As for the newline, either remove it with chomp or leave it (remove chomp). I don't see why a newline would be needed on a string that goes into a spreadsheet.




回答2:


Since $csv->say is at the end of the program, and it's not in a loop, it will only ever print one line. It will have every pair and every result.

$csv->say ($out, [@pairs, @result]);

I'm not sure what you're trying to accomplish, but you probably want to print your results inside a loop.



来源:https://stackoverflow.com/questions/37149051/perl-output-still-only-one-line

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!