我有两个文件都遵循相同的模式:
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
的简单方法?
答案 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;
}
您只需将该文件作为参数。