Вычислить числовые значения из текстового файла, разделенного пробелами, в диапазоне строк - PullRequest
1 голос
/ 22 апреля 2009

У меня есть файл со следующими значениями:

for 3 threads:
Average time taken for API1 is: 19097.7 nanoseconds.
Average time taken for API2 is: 19173.1 nanoseconds.
Average time taken for API2 is: 19777.7 nanoseconds.
Average time taken for API2 is: 19243.1 nanoseconds.
Average time taken for API1 is: 19737.7 nanoseconds.
Average time taken for API2 is: 19128.1 nanoseconds.
for 5 threads:
Average time taken for API1 is: 19097.7 nanoseconds.
Average time taken for API2 is: 19173.1 nanoseconds.
Average time taken for API2 is: 19777.7 nanoseconds.
...

Я хочу вычислить сумму строк 1API и строк 2API и суммировать их. Другое требование состоит в том, что я также хочу выяснить для каждого потока на отдельной основе. Есть ли способ сделать это, используя perl, sed, awk или просто сценарии оболочки?

Что я могу получить сейчас:

cat result | grep API1 | awk {'print $7'}

Ответы [ 3 ]

2 голосов
/ 22 апреля 2009

Вы можете использовать комбинацию grep en awk. grep для выбора только строк с данными (где API) и awk для подсчета.

grep API file | awk '{ arr[$5]+=$7 } END {for (i in arr) {print i,arr[i]}   } ' -

(изменить файл с именем файла или удалить для чтения из стандартного ввода)

Если вы хотите рассчитать различные суммы, вы можете сделать это

awk '{ if($1 == "for") id = $2; else arr[id $5]+=$7 } END {for (i in arr) {print i,arr[i]}   } ' testfile

Выход:

5API1 19097.7
5API2 38950.8
3API1 38835.4
3API2 77322
0 голосов
/ 22 апреля 2009

Я не понимаю ваше последнее требование (там не указано никаких потоков), но я предоставлю вам настройку для этой информации и выполню требование, которое может понять Данные разбиты, так что вы можете добраться до них. И хотя я не понимаю, как бы вы использовали строку 'for x threads:', она по крайней мере захвачена, поэтому вы можете работать с ней.

use List::Util qw<sum>;

my $fh = FileHandle->new( PATH_TO_DATAFILE );
my $data 
    = { trial_times => []
      , totals      => {}
      };
my $precision = 0;

while ( <$fh> ) { 
    if ( m/^for (\d+) threads:/ ) { 
        push @{$data->{trial_times}}, {};
    }
    elsif ( m/^Average time taken for (API\w+) is: (\d+\.(\d+)) nanoseconds./ ) {
        push @{$data->{trial_times}[-1]{$1}}, $2;
        push @{ $data->{totals}->{$1} }, $2;
        $precision = length $3 if length $3 > $precision;
    }
}

### $data

foreach my $api ( keys %{ $data->{totals} } ) { 
    my @list = @{ $data->{totals}{$api} };
    my $sum  =sum @list;

    printf "Sum for %d runs of API $api: %0.${precision}f (Average: %0.${precision}f)\n"
         , scalar @list, $sum, $sum / scalar @list
         ;
}

my @combined = map { @$_ } values %{$data->{totals}};
### @combined
my $sum      = sum @combined;
printf "Combined %d runs for %0.${precision}f total (Average: %0.${precision}f)\n"
    , scalar @combined, $sum, $sum / scalar @combined
    ;
0 голосов
/ 22 апреля 2009

короткие и нечитаемые:

perl -lane 'END{&h}sub h{print"\t$_ => $h{$_}"for keys%h;%h=()}&h,print,next if/^for/;$h{$F[4]}+=$F[6]' data

Читаемый, но должен быть скрипт:

#!/usr/bn/perl

use strict;
use warnings;

my %counts;
my $thread = "undefined";
while (<>) {
    if (/^for ([0-9]+)/) {
        $thread = $1;
        next;
    }
    my ($item, $time) = /for (\S+) is: (\S+) nano/;
    $counts{$thread}{$item} += $time;
}

for my $thread (sort { $a <=> $b } keys %counts) {
    print "for $thread threads:\n";
    for my $item (sort keys %{$counts{$thread}}) {
        print "\t$item => $counts{$thread}{$item}\n";
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...