问题
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