使用awk从文件计算时间

使用awk从文件计算时间,awk,Awk,我想根据我拥有的文件计算响应时间。响应时间将是从源(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

我想根据我拥有的文件计算响应时间。响应时间将是从源(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)

这行显示应答从2端口0($9)到 接收到源6端口0($10),而示例中的第一行:

 + 0.1 6 0 tcp 40 ------- 1 6.0 2.0 0 0    
显示由源(6)端口0($9)向目标(2)端口0($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

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

好的-我不太了解文件的映射,但是根据这个例子,这里有一个可能的框架,可以为您提供一个可行的解决方案

#!/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”。从表面上看,这种技术最终只能用于打印差异

我从输入文件中去掉了“…”行(而不是用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”,然后:

生成所请求的输出:

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

通过管道将其分类后。我想这个问题比我在这个编辑中描述的更复杂,因为基于新键的重复起始行。如果有更多的独特信息可以提供给每个键,这会有所帮助。

您的好问题可以通过添加并明确标记“基于上述示例输入的所需输出”部分来解决。您可能还希望标记任何希望被跳过的输入行,并使用类似于“#skip”的尾随注释。祝你好运谢谢你的提示。检查更新!对不起,我真的没有把它作为示例输出。如果需要这些文字字符串,只需打印“响应时间\n-----------------\n值”。祝你好运。这些文件有多大?如果它们不是太大,我建议使用awks关联数组(贴图),方法是创建一个可以从起始线和终止线生成的键。然后,您可以存储任何您想要的值,比如使用delimeters,并解析它们以在结束块中显示。我会尝试模拟一些东西,但我不太理解你的领域/要求,正如问题所述。请尽量把长话短说,更切题。数据的解释是不必要的,但结构。这是如此接近我想要的框架。然而,我在运行代码时遇到了两个问题。我得到一个错误,之后的代码继续运行并生成输出:第2行:$“r”命令未找到。这个错误不是问题,我可以解决它。但是,我需要理解输出:key=2:40:2.0,value=0.122096,我不理解键值。我需要密钥:source.port 2.port-->响应时间=差异。将更新问题。非常感谢,谢谢你,它很管用。我仍然不确定为什么每条线路都有不同的端口号,即来源:15.738-2.8024。应该是一样的!!!我很高兴它对你有用。我以前从未见过NS2格式的文件。我无法推测为什么原始数据文件中的源端口号没有对齐。祝你好运
#!/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