Reputation: 4808
I have two files which both follow the same pattern:
TEST CASE 1: 0.004 seconds
TEST CASE 2: 0.043 seconds
TEST CASE 3: 0.234 seconds
TEST CASE 4: 0.564 seconds
....
What I'm trying to do is calculate the speedup for each test case, which is done by taking the value from one file and dividing it with the corresponding value in the other file.
Is there a simple way of doing that using awk
?
Upvotes: 3
Views: 871
Reputation: 4808
I managed to come up with my own solution by using paste
to merge the two result files. Then the awk
script became really simple, and the test cases are sorted correctly.
paste <(grep "^TEST CASE" file1) <(grep "^TEST CASE" file2) |
awk '{print "TEST CASE " $3 " " $4 / $9}'
The grep
is there to get the expected input to paste
as the lines are taken from a file which contains a lot of other information that I don't want. If the expected output is already available in a separate file (as I stated in the question), then the command becomes
paste file1 file2 | awk '{print "TEST CASE " $3 " " $4 / $9}'
This gives as output:
TEST CASE 1: 1.0423
TEST CASE 2: 2.34023
TEST CASE 3: 3.2423
TEST CASE 4: 4.3425
....
Upvotes: 1
Reputation: 882786
If they have the same test cases, you can simply combine the two files in a sorted manner then use awk
to process the resultant stream, storing the first time for each pair and then calculating on the second time.
Something like in the following transcript:
pax:~$ cat file1
TEST CASE 1: 0.004 seconds
TEST CASE 2: 0.043 seconds
TEST CASE 3: 0.234 seconds
TEST CASE 4: 0.564 seconds
pax:~$ cat file2
TEST CASE 1: 0.003 seconds
TEST CASE 2: 0.040 seconds
TEST CASE 3: 0.134 seconds
TEST CASE 4: 0.664 seconds
pax:~$ ( cat file1 |sed 's/:/: A /' ; cat file2 |sed 's/:/: B /' ) |sort |awk '{
if (state == 0) {
before = $5;
state = 1;
} else {
print before" -> "$5" ("("int(100 * $5 / before - 100)"%)")"
state = 0;
}
}'
0.004 -> 0.003 (-25%)
0.043 -> 0.040 (-6%)
0.234 -> 0.134 (-42%)
0.564 -> 0.664 (17%)
Here's how it works. The subshell ( ... )
changes both files so they'll sort correctly with a simple sort
command into the following:
TEST CASE 1: A 0.004 seconds
TEST CASE 1: B 0.003 seconds
TEST CASE 2: A 0.043 seconds
TEST CASE 2: B 0.040 seconds
TEST CASE 3: A 0.234 seconds
TEST CASE 3: B 0.134 seconds
TEST CASE 4: A 0.564 seconds
TEST CASE 4: B 0.664 seconds
In other words, into pairs of before and after values. The awk
then has a mini state machine with two states. In state zero, it simply stores the before time and sets the state to one. In state one, it calculates and prints the required values before setting the state back to zero.
If you want the test case number included and natural sorting, you can use (after adding test case 10 to the input files):
pax:~$ ( cat file1 |sed 's/:/: A /' ; cat file2 |sed 's/:/: B /' ) |sort |awk '{
if (s == 0) {
s = 1;
before = $5;
} else {
s = 0;
printf "%5s %s->%s (%d%%)\n", $3, before, $5, int(100 * $5 / before - 100)
}
}' |sort -n
1: 0.004->0.003 (-25%)
2: 0.043->0.040 (-6%)
3: 0.234->0.134 (-42%)
4: 0.564->0.664 (17%)
10: 0.564->0.764 (35%)
Upvotes: 3
Reputation: 1379
It's not exactly what you've asked for, but until someone provides a solution using awk, you're stuck with me and I only know perl :)
#!/usr/bin/perl
use strict;
use warnings;
my $zaehler = 0;
while (<>) {
/:\s*([\d.]*) s/;
print(($zaehler/$1)."\n");
$zaehler = $1;
}
You just give the file as an argument.
Upvotes: 0