如何使用awk处理两个结果文件?

时间:2011-12-28 09:33:17

标签: awk

我有两个文件都遵循相同的模式:

TEST CASE 1:  0.004 seconds
TEST CASE 2:  0.043 seconds
TEST CASE 3:  0.234 seconds
TEST CASE 4:  0.564 seconds
....

我要做的是计算每个测试用例的加速比,这是通过获取 来自一个文件的值,并将其除以另一个文件中的相应值。

是否有使用awk的简单方法?

3 个答案:

答案 0 :(得分:3)

如果它们具有相同的测试用例,您可以简单地以排序的方式组合这两个文件,然后使用awk处理结果流,为每对存储第一次,然后在第二次计算。

以下成绩单中的内容:

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%)

这是它的工作原理。子shell ( ... )更改了这两个文件,因此它们将使用简单的sort命令正确排序到以下内容中:

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

换句话说,成对的前后值。然后awk有一个具有两种状态的迷你状态机。在状态0,它只是存储前一时间并将状态设置为一。在状态1中,它在将状态设置回零之前计算并打印所需的值。


如果您希望包含测试用例编号和自然排序,则可以使用(在将测试用例10添加到输入文件之后):

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%)

答案 1 :(得分:1)

我设法通过使用paste合并两个结果文件来提出我自己的解决方案。然后awk脚本变得非常简单,测试用例正确排序。

paste <(grep "^TEST CASE" file1) <(grep "^TEST CASE" file2) |
awk '{print "TEST CASE " $3 "  " $4 / $9}'

grep可以获得paste的预期输入,因为这些行是从包含我不想要的许多其他信息的文件中获取的。如果预期输出已在单独的文件中可用(如我在问题中所述),则命令变为

paste file1 file2 | awk '{print "TEST CASE " $3 "  " $4 / $9}'

这给出了输出:

TEST CASE 1:  1.0423
TEST CASE 2:  2.34023
TEST CASE 3:  3.2423
TEST CASE 4:  4.3425
....

答案 2 :(得分:0)

这不完全是你要求的,但是在有人使用awk提供解决方案之前,你会被我困住,我只知道perl:)

#!/usr/bin/perl

use strict;
use warnings;

my $zaehler = 0;

while (<>) {
  /:\s*([\d.]*) s/;
  print(($zaehler/$1)."\n");
  $zaehler = $1;
}

您只需将该文件作为参数。

相关问题