2009-04-22 6 views
1

ich eine Datei mit den folgenden Werten haben:Compute numerische Werte von einem Leerzeichen getrennte Textdatei, in einem Bereich von Linien

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. 
... 

Ich möchte die Summe der 1API Leitungen und den 2API Linien berechnen und summiere sie. Eine weitere Anforderung ist, dass ich auch für jeden Thread auf einer separaten Basis herausfinden möchte. Gibt es eine Möglichkeit, dies per Perl, sed, awk oder nur Shell-Skripten zu tun?

Was kann ich aktuelle get ist:

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

Antwort

2

Sie eine Kombination aus grep en awk verwenden können. grep, um nur die Zeilen mit Daten (wo sich API befindet) und awk für das Zählen auszuwählen.

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

(Änderung Datei mit dem Dateinamen oder entfernen, um von stdin lesen)

Wenn Sie die verschiedenen Summen berechnen möchten, können Sie tun, um diesen

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

Ausgang:

5API1 19097.7 
5API2 38950.8 
3API1 38835.4 
3API2 77322 
0

kurz und unlesbar:

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

Lesbare, sondern muss ein Skript sein:

#!/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"; 
    } 
} 
+0

hi, dies erfüllt nicht die Anforderung, unterschiedliche Summen für die unterschiedliche Anzahl der angegebenen Threads zu haben. – gagneet

+0

Es würde tun, wenn der erste Regex in der While-Schleife korrekt war ... – Alnitak

+0

@Alnitak es sieht gut aus und ich testete den Code auf die bereitgestellten Daten, was denkst du ist falsch? –

0

Ich verstehe nicht Ihre letzte Anforderung (es sind kein Thema angegeben), aber ich werde Sie ein Setup erhalten für diese Informationen und erfüllen die Anforderung I kann verstehen. Die Daten sind aufgeteilt, so dass Sie darauf zugreifen können. Und obwohl ich nicht verstehe, wie Sie die Zeile "for x threads:" verwenden, wird sie zumindest erfasst, sodass Sie möglicherweise damit arbeiten können.

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 
    ;