Perl:输出仍然只有一行 [英] Perl: output still only one line
问题描述
这是同一个项目的第三个问题:
我试图grep字符串距离:从pairsAngles.txt每个超过2000个子目录;子目录的名称从csv文件获取。
通过eol => $ /到Text :: CSV_XS-> new并使用$ csv->说,输出仍然是一行...
#!/ usr / bin / perl -w
use strict;
使用警告;
use File :: Find;
使用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无法打开\$ cluster\:$!;
my $ cU =clst1Updated.csv;
open($ out,> $ cU)||死不能打开'$ 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匹配{
open($ pairs,pairsAngles.txt)或die$!;
while(my $ dist =< $ pairs>){
if($ dist =〜m / Distance:/){
chomp $ dist;
push(@result,$ dist\\\
);
}
}
}
}
chdir..;
if(not $ csv-> eof){
$ csv-> error_diag();
}
$ csv-> say($ out,[@pairs,@result]);
close $ out或die$!;
我看不到你想如何结合 @pairs
和 @result
,但是要将整个数组写入您需要的电子表格, Text :: CSV_XS文档
$ csv-> say($ fh,$ _)for @rows;让我们知道如何
应在输出中配对以获取更多详细信息。@pairs
和 code> @result
澄清:写入的行应该有一个单元格的目录和另一个对应的匹配行,我们知道确切的是,每个文件中只有一个这样的匹配。
if(@pairs!= @result){
dieMismatching lengths:directory。标量(@pairs)。
vs matches。标量(@result);
}
for my $ i(0 .. $#pairs){
$ csv-> say($ out,[$ pairs [$ i],$ result [$ i] ]);
}
请注意
@pairs!= @result
不会 防止所有可能的意外不匹配,它更多的是在代码中包括更严格的检查。 (例如,在一个文件中可能有一个不匹配但在另一个文件中有两个匹配,并且数组将以相同的长度结束。)检查@result
是否添加到将测试确实只有一个匹配。
注意。在一个地方的代码删除了
chomp
的新行,但后来将其放回\\\
。
chomp $ dist;
push(@result,$ dist\\\
);
不需要
\\\
则不需要
- 只需
push @result,$ dist;
。对于换行符,可以使用chomp
删除它或保留它(删除chomp
)。我不明白为什么需要一个换行符进入电子表格的字符串。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 "$!";
解决方案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 -- justpush @result, $dist;
. As for the newline, either remove it withchomp
or leave it (removechomp
). I don't see why a newline would be needed on a string that goes into a spreadsheet.这篇关于Perl:输出仍然只有一行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!