我有一个包含以下数据的文件。我想打印一个外部文件,每9行总和。这是我的数据。
file.xyz
-0.485718003092488 3.25568455554021 -0.60544991716881
-1.01253068155602 -2.49251542491767 0.713923699625837
0.791137982988487 -2.56492609246597 -0.853251541212567
-0.485718003092488 3.25568455554021 -0.60544991716881
-1.01253068155602 -2.49251542491767 0.713923699625837
0.791137982988487 -2.56492609246597 -0.853251541212567
-0.485718003092488 3.25568455554021 -0.60544991716881
-1.01253068155602 -2.49251542491767 0.713923699625837
0.791137982988487 -2.56492609246597 -0.853251541212567
-0.485718003092488 3.25568455554021 -0.60544991716881
-1.01253068155602 -2.49251542491767 0.713923699625837
0.791137982988487 -2.56492609246597 -0.853251541212567
-0.485718003092488 3.25568455554021 -0.60544991716881
-1.01253068155602 -2.49251542491767 0.713923699625837
0.791137982988487 -2.56492609246597 -0.853251541212567
-0.485718003092488 3.25568455554021 -0.60544991716881
-1.01253068155602 -2.49251542491767 0.713923699625837
0.791137982988487 -2.56492609246597 -0.853251541212567
我的输出看起来像
-2.121332105 -5.405270886 -2.234333276 6.221675693
-2.121332105 -5.405270886 -2.234333276 6.221675693
第一行是1-9的总和,第二行是10-18的总和。这里前9行和后9行的数据相同,它给出相同的值。我想用千行文件打印每个NINE大行文件的总和。
这是我的代码,它计算总和,但我需要分成两部分,如上所述。
感谢您的帮助和赞赏。
my @sums;
open FILE, "file.xyz" or die "Can't find";
while( <FILE> ) { # there is FILE written within angular brackets
my @summands = split / /;
foreach my $i ( 0 .. $#summands ) {
$sums[$i] += $summands[$i];
}
}
$total = sqrt($sums[0]*$sums[0]+$sums[1]*$sums[1]+$sums[2]*$sums[2]);
print "$sums[0], $sums[1], $sums[2], $total\n";
答案 0 :(得分:2)
如下所示:
use strict;
use warnings;
use autodie;
open my $fh, '<', 'file.xyz';
my @sums;
my $n = 0;
while (<$fh>) {
my @summands = split /\s+/;
foreach my $i ( 0 .. $#summands ) {
$sums[$i] += $summands[$i];
}
unless ( ++$n % 9 ) {
my $total = sqrt( $sums[0] * $sums[0] + $sums[1] * $sums[1] + $sums[2] * $sums[2] );
print "$sums[0], $sums[1], $sums[2], $total\n";
@sums = ();
}
}
答案 1 :(得分:1)
添加行计数器并将$total
和print
代码移动到条件下的循环中。你还需要清除那里的总和。
if ($lines % 9 == 0) {
...
}
答案 2 :(得分:0)
使用输入行号$.
确定每9行的时间:
use strict;
use warnings;
use autodie;
use List::Util qw(sum);
#open my $fh, '<', "file.xyz";
my $fh = \*DATA;
my @sums;
while (<$fh>) {
my @cols = split ' ';
for my $i ( 0 .. $#cols ) {
$sums[$i] += $cols[$i];
}
if ( ( $. % 9 ) == 0 or eof ) {
my $weighted_total = sqrt sum map $_**2, @sums;
print join( ', ', @sums, $weighted_total ), "\n";
@sums = ();
}
}
warn "FH did not end an on even multiple of 9" if $. % 9;
__DATA__
-0.485718003092488 3.25568455554021 -0.60544991716881
-1.01253068155602 -2.49251542491767 0.713923699625837
0.791137982988487 -2.56492609246597 -0.853251541212567
-0.485718003092488 3.25568455554021 -0.60544991716881
-1.01253068155602 -2.49251542491767 0.713923699625837
0.791137982988487 -2.56492609246597 -0.853251541212567
-0.485718003092488 3.25568455554021 -0.60544991716881
-1.01253068155602 -2.49251542491767 0.713923699625837
0.791137982988487 -2.56492609246597 -0.853251541212567
-0.485718003092488 3.25568455554021 -0.60544991716881
-1.01253068155602 -2.49251542491767 0.713923699625837
0.791137982988487 -2.56492609246597 -0.853251541212567
-0.485718003092488 3.25568455554021 -0.60544991716881
-1.01253068155602 -2.49251542491767 0.713923699625837
0.791137982988487 -2.56492609246597 -0.853251541212567
-0.485718003092488 3.25568455554021 -0.60544991716881
-1.01253068155602 -2.49251542491767 0.713923699625837
0.791137982988487 -2.56492609246597 -0.853251541212567
输出:
-2.12133210498006, -5.40527088553029, -2.23433327626662, 6.22167569349391
-2.12133210498006, -5.40527088553029, -2.23433327626662, 6.22167569349391
答案 3 :(得分:-1)
整个Perl-golf风格的东西,用一些空白和缩进来淡化:
while (<>) {
@l = split;
@s = map { $s[$_] + $l[$_] } 0..$#l;
next if ++$n % 9;
$, = ' ';
print @s, sqrt(eval join '+', (map { $_*$_ } @s)), "\n";
@s = ();
}
一些真正的Perl-golf,受到@Nemo的启发,但更短:
perl -lanE '$s[$_]+=$F[$_]for 0..$#F;$.%9&&next;print"@s @{[sqrt eval join qq(+),map $_**2,@s]}";@s=()'
找到使用过的技巧留给读者练习。 : - )