【问题标题】:Calculate a time from file with awk使用 awk 从文件计算时间
【发布时间】:2013-11-04 09:36:57
【问题描述】:

我想从我拥有的文件中计算响应时间。响应时间将是从源 (A) 发送数据包到源 (A) 从目标 (B) 接收到 ack 之间的时间。使用 awk 将是提取响应时间的答案。但是,我对如何应用逻辑有点困惑。跟踪文件的下面部分:

 + 0.1 6 0 tcp 40 ------- 1 6.0 2.0 0 0
 - 0.1 6 0 tcp 40 ------- 1 6.0 2.0 0 0
 + 0.101172 6 0 tcp 40 ------- 1 6.1 2.1 0 1
 - 0.102032 0 1 tcp 40 ------- 1 6.0 2.0 0 0
 + 0.102394 6 0 tcp 40 ------- 1 6.2 2.2 0 2
 .......
  .....
 + 0.112517 6 0 tcp 40 ------- 1 6.6 2.6 0 6
 + 0.122096 1 2 tcp 40 ------- 1 6.0 2.0 0 0
 .....
 r 0.148256 0 6 ack 40 ------- 1 2.0 6.0 0 7
 r 0.149428 0 6 ack 40 ------- 1 2.1 6.1 0 8
 ...

在此示例中,我将重点关注源 (6) 和目标 (2) 之间的通信。所以响应时间为(0.148256 - 0.1)。

r 0.148256 0 6 ack 40 ------- 1 2.0 6.0 0 7  

这一行显示从 2 端口 0 ($9) 到 ack 的回复 source 6 端口 0 ($10) 被接收,而示例中的第一行:

 + 0.1 6 0 tcp 40 ------- 1 6.0 2.0 0 0    

显示请求是由源 (6) 端口 0 ($9) 向目标 (2) 端口 ($10) 发出的。 整个跟踪文件的目标始终是(2),我在想类似的东西: 注意:每次更改端口号(是 $9 或 $10 的一部分)时,都意味着新的请求连接。

记录发起请求的时间:

$1 == "+" && $5 == "tcp" && $6 == 40 && $10== 2.port && $9==source.port ) {
print $2; // would be the start 
}

记录收到回复的时间;

 $1 == "r" && $5 == "ack" && $6 == 40 && $9== 2.port && $10==source.port ) {
print $2;  // would be the end 
}

预期的输出可以有两种方式作为一列:

1) 基于流 id,即流 1:

    source: 6.0 - 2.0 ---> response time: 0.148256 - 0.1
    source: 6.1 - 2.1 ---> response time : end-start
    source: any source.port-2.port --> response time : end-start

我的问题我不确定如何自动化代码,所以我可以查看整个跟踪文件并存储响应时间的值。最后我想要图形响应时间。有什么建议么?不要介意其他脚本语言!

【问题讨论】:

  • 您的好问题可以通过添加并明确标记“基于上述示例输入的所需输出”部分来解决。您可能还希望使用诸如“#skip”之类的尾随注释来标记您希望跳过的任何输入行。祝你好运!
  • 感谢您的提示。检查更新!
  • 对不起,我真的没有把它作为示例输出。如果您想要这些文字字符串,只需执行print " response time\n-------------------\n values"。祝你好运。
  • 这些文件有多大?如果它们不是太大,我建议使用 awks 关联数组(映射),方法是创建一个可以从开始行和停止行生成的键。然后你可以存储你想要的任何值,比如使用分隔符并解析它们以在 END 块中显示。我会尝试模拟一些东西,但我不太了解您提出的问题的领域/要求。
  • 请尽量使长篇故事更短,更切中要害。不需要解释数据,但需要解释结构。

标签: awk


【解决方案1】:

好的 - 我不太了解文件的映射,但根据示例,这里有一个可能适用于您的解决方案的框架。

#!/bin/sh

awk '

$1 == "+" && $5 == "tcp" { garr[ makeKey( $4, $6, $10 ) ] = $2 }

$1 == "r" && $5 == "ack" {
    key = makeKey( $3, $6, $9 )
    if( key in garr )
        garr[ key ] = sprintf( "d%f", ($2+0.0) - (garr[ key ]+0.0) )
    }

END {
    for( key in garr )
        printf( "key = %s, value = %s\n", key, garr[ key ] )
    }

    function makeKey( arg1, arg2, arg3 ) {
        return sprintf( "%s:%s:%s", arg1, arg2, arg3 )
    }

' $1

有一个函数 makeKey() 可以为全局数组 garr 生成键。每当有起始行时,输入一个值。当有结束行时,尝试计算差异。然后将差异存储在相同的密钥位置,但前面有一个“d”。这种技术表面上可以用于仅打印 END 中的差异。

我从输入文件中删除了“....”行(而不是用 awk 忽略它们)并将它们放入一个名为“data”的文件中。

我将代码放入名为“elap”和“chmod +x elap”的文件中,以使其可执行。下面是一个运行它的例子:

prompt> elap data
key = 2:40:2.0, value = 0.122096
key = 1:40:2.0, value = 0.102032
key = 2:40:2.1, value = 0.123268
key = 0:40:2.0, value = d0.048256
key = 0:40:2.1, value = 0.101172
key = 1:40:2.5, value = 0.112802
key = 0:40:2.2, value = 0.102394
key = 1:40:2.6, value = 0.114549
key = 0:40:2.6, value = 0.112517

可以更改最终输出以匹配您想要的格式。发现的唯一区别是在输出的第 4 行并且具有“value = d0.048256” - 这应该来自您的示例案例。

密钥可能不够复杂,无法跟踪写入时在同一源和目标之间经过的多个实例。


更改问题后,我更改了答案,但保留了原始答案,因为它显示了如何产生第二个脚本没有做的差异。不太清楚这里的礼仪是什么。

这是“elap2”然后:

#!/bin/sh

awk '

BEGIN { DELIM = " - " }

    # grab "start" rows, ignore them if they are already in garr
$1 == "+" && $5 == "tcp" && $6 == 40 {
    key = makeKey( $9, $10 )
    if( !(key in garr) )
        garr[ key ] = $2
    }

$1 == "r" && $5 == "ack" && $6 == 40 {
    key = makeKey( $10, $9 )
    if( key in garr )
        garr[ key ] = sprintf( "%s%s%s", $2, DELIM, garr[ key ] )
    }

END {
    for( key in garr )
        {
        value = garr[ key ]
        # get the values back out here - only print entries with elapsed times
        if( split( value, varr, DELIM ) == 2 )
            printf( "source: %s ---> response time: %s%s%s\n", key,
                varr[1], DELIM, varr[2] )
        }
    }

    function makeKey( source, destination ) {
        return sprintf( "%s%s%s", source, DELIM, destination )
    }

' $1

产生请求的输出:

source: 6.0 - 2.0 ---> response time: 0.148256 - 0.1
source: 6.1 - 2.1 ---> response time: 0.149428 - 0.101172

在通过排序管道之后。我想这个问题比我在这个编辑中表示的更复杂,因为基于新键的重复起始行。如果每个键都有更多独特的信息,那会有所帮助。

【讨论】:

  • 这与我想要的框架非常接近。但是,当我运行代码时,我遇到了两个问题。我收到一个错误,之后的代码继续运行并产生输出:line 2:$"r"command not found。这个错误不是问题,我可以解决它。但是,我需要了解输出:key = 2:40:2.0, value = 0.122096,我不了解键值。我需要有 key:source.port 2.port-->response time=difference。将更新问题。非常感谢
  • 谢谢它有效。我仍然不确定为什么我为每条线路获得不同的端口号,即源:15.738 - 2.8024。应该是一样的!!!
  • 我很高兴它对你有用。我以前从未见过 NS2 格式的文件。我无法推测为什么源端口号不在原始数据文件中排列。祝你好运!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-26
  • 1970-01-01
  • 2020-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多