2014-09-22 3 views
2

У меня есть файл со следующими данными. Я хочу напечатать во внешнем файле с суммой из каждых 9 строк. Вот мои данные.Нужна помощь в Perl looping

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.5 -5.405270886 -2.234333276 6.221675693 
-2.5 -5.405270886 -2.234333276 6.221675693 

Если первая строка сумма 1-9 и вторая линия сумма от 10-18. Здесь данные одинаковы для первых 9 и последних 9 строк, он дает то же значение. Я хочу напечатать сумму из всех строк больших файлов с тысячами строк.

Вот мой код, он вычисляет общую сумму, но мне нужно разделить на две части, как указано выше.

Благодарим за помощь и ценю.

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"; 
+1

Я думаю, что вы хотите, чтобы сумма каждых 9 строк, не колонны. Лучше использовать три аргумента формы «открыть», чтобы открыть файл. Вы можете использовать '$ row_number% 9 == 0', чтобы проверить, делится ли текущая строка на 9. – sockmonk

+0

Здравствуйте @sockmonk, Да, это НЕ столбцы, это строки. Где я могу добавить это? это то, что мне нужно. Мне нужен новый цикл, который подсчитывает строки и печатает до тех пор, и снова запустит цикл ... Я плохо разбираюсь в программировании. – bikesh

+0

Спасибо всем. Это много значит для меня ... – bikesh

ответ

1

Добавить счетчик строк и перемещать $total и print код в петлю под условным. Вам также нужно будет очистить суммы.

if ($lines % 9 == 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

Все дело в стиле Perl-гольф, разбавленные с небольшим количеством пробелов и отступов:

while (<>) { 
    @l = split; 
    @s = map { $s[$_] + $l[$_] } 0..$#l; 
    next if ++$n % 9; 
    $, = ' '; 
    print @s, sqrt(eval join '+', (map { $_*$_ } @s)), "\n"; 
    @s =(); 
} 

И некоторые реальные Perl- гольф, вдохновленный @Nemo, но еще короче:

perl -lanE '$s[$_]+=$F[$_]for 0..$#F;$.%9&&next;print"@s @{[sqrt eval join qq(+),map $_**2,@s]}";@s=()' 

Поиск использованных трюков оставлен в качестве упражнения для читателей. :-)

+3

Гольф? 'perl -MList :: Util = sum -lanE '$ s [$ _] + = $ F [$ _] для 0 .. $ # F; $.% 9 &&next; print" @s @ {[sqrt sum map $ _ ** 2, @ s]} "; @ s =() '' – Nemo

+0

Очень приятно !!! :-) – SzG

+0

Интересно, был ли я ниспровергнут строгим предупреждением фанатика, или довольно блестящим победителем в соревновании по гольфу, Nemo ... :-) – SzG

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.498006, -5.40527088553029, -2.23433327626662, 6.22167569349391 
-2.498006, -5.40527088553029, -2.23433327626662, 6.22167569349391