您的位置:首页 > 其它

Reading Notes on NS2(11)

2009-11-20 22:36 344 查看
数据分析



使用gawk分析Trace文件

[1] gawk

awk是一种程序语言。它具有一般程序语言常见的功能。

注意:

(1)awk书写程序比使用其他语言更简洁、便利且节省时间。

(2)awk善于处理具有记录(record)字段(field)等形态的数据。

(3)awk可以配合管道(pipe)一起使用。

gawk是GNU所开发的awk,最初在1986年完成,之后不断地改进和更新。gawk包含awk的所有功能。

[2] gawk读取Trace文件

记录(record)是gawk从输入文件中读取的基本单位。(一般而言,一条记录相当于数据文件中的一行数据)

字段(field)是记录被分割开的字符串。(一般而言,是以空格符来分隔相邻的字段)

注意:

(1)当gawk读入记录后,会把每个的值自动存入字段变量。

字段变量 意义

$0 内容为awk所读入的一条记录

$1 代表$0上第一个字段的数据

$2 代表$0上第二个字段的数据

...

[3] gawk程序的主要结构

gawk的主要功能是针对文件的每一条记录搜寻指定的模式(patterns)。gawk依次处理输入文件的每一条记录,直到输入文件结束为止。

注意:

(1)一般常用“关系判断式”来构造pattern。

(2)awk提供C语言常见的关系操作符。

(3)有两个特殊的pattern,分别是BEGIN和END,表示gawk在开始执行和结束时会分别执行BEGIN和END指定的action。注意!BEGIN和END中的action在整个处理过程中只执行一次,而不对每条记录都执行。

[4] gawk的基本命令

(1)IO命令

(a)print命令:用在简单、标准的输出格式。

print后面不跟东西等同于print $0,会输出当前的记录。

print "" 输出空白行。

print "Hi,wcdj" 输出一串文字。

(b)printf命令:能够精确地控制输出格式。

用法和C语言的printf相同。

(2)流程控制指令

(a)条件语句

if(x%2==0)

print "x is even"

else

print "x is odd"

(b)循环语句

while、for同C语言用法

(c)运算指令

运算指令包括算术运算、逻辑运算等。同C语言。

[5] gawk程序的工作流程

执行awk程序时,它会反复进行下面4个步骤:

(1)自动从指定的输入文件中读取一条记录。

(2)自动更新相关的内建变量值。

(3)逐次执行程序中所有的命令。

(4)当此记录执行完所有命令时,若还有记录则重新从(1)开始执行,直到所有记录都执行一遍。

注意:

awk会自动重复进行上述的四个步骤。

[6] gawk的执行方法

(1)如果gawk程序很短,则程序代码可以直接写在命令行上。

(2)如果gawk程序较长,则将gawk程序存为一个文件。(此方法常用)

[7] 使用gawk进行数据分析的实例

#使用gawk对以前一Tcl例子输出的Trace文件out.tr进行分析
#分析分组端到端的时延(End to End Delay)
#主要讨论网络传输时延

#将下面测量CBR分组端到端的时延gawk代码存放在文件measure-delay.awk文件中

BEGIN {
#程序初始化,设定一变量以记录目前最高处理分组的ID
     highest_packet_id=0;
}

{
	action=$1;
	time=$2;
	node_1=$3;
	node_2=$4;
	type=$5;
	flow_id=$8;
	node_1_address=$9;
	node_2_address=$10;
	seq_no=$11;
	packet_id=$12;

	#记录目前最高的分组ID
	if(packet_id > highest_packet_id)
	   highest_packet_id=packet_id;

	#记录分组的传送时间
	if(start_time[packet_id]==0)   #此条件约束第一次出现的分组
	   start_time[packet_id]=time;

	#记录CBR(flow_id=2)的接收时间
	if(flow_id==2 && action=="r")
	   end_time[packet_id]=time;
	else
	   end_time[packet_id]=-1;
}   

END {
#当输入数据全部读取完后,开始计算有效分组的端点到端点延迟时间
    for(packet_id=0 ; packet_id<=highest_packet_id ; packet_id++) {
        start=start_time[packet_id];
        end=end_time[packet_id];
        packet_duration=end-start;
        
        #只把接收时间大于传送时间的记录列出来
        if(start<end)
           printf("StartTime:%f DurationTime:%f/n",start,packet_duration);
    }
}    

#
#更简单的写法如下
#

BEGIN {
#程序初始化,设定一变量以记录目前最高处理分组的ID
     highest_packet_id=0
}

{
	action=$1
	time=$2
	node_1=$3
	node_2=$4
	type=$5
	flow_id=$8
	node_1_address=$9
	node_2_address=$10
	seq_no=$11
	packet_id=$12

	#记录目前最高的分组ID
	if(packet_id > highest_packet_id)
	   highest_packet_id=packet_id

	#记录分组的传送时间
	if(start_time[packet_id]==0)   #此条件约束第一次出现的分组
	   start_time[packet_id]=time

	#记录CBR(flow_id=2)的接收时间
	if(flow_id==2 && action=="r")
	   end_time[packet_id]=time
	else
	   end_time[packet_id]=-1
}   

END {
#当输入数据全部读取完后,开始计算有效分组的端点到端点延迟时间
    for(packet_id=0 ; packet_id<=highest_packet_id ; packet_id++) {
        start=start_time[packet_id]
        end=end_time[packet_id]
        packet_duration=end-start
        
        #只把接收时间大于传送时间的记录列出来
        if(start<end)
           printf("StartTime:%f   DurationTime:%f/n",start,packet_duration);
           #printf "StartTime:%f   DurationTime:%f/n",start,packet_duration   #ok
    }
}    

#执行方法
$gawk -f measure-delay.awk out.tr > cbr_delay
#打开cdr_delay文件查看执行结果
$more cdr_delay
#可以得到如下内容

StartTime:0.100000   DurationTime:0.038706
StartTime:0.108000   DurationTime:0.038706
StartTime:0.116000   DurationTime:0.038706
StartTime:0.124000   DurationTime:0.038706
StartTime:0.132000   DurationTime:0.038706
StartTime:0.140000   DurationTime:0.038706
StartTime:0.148000   DurationTime:0.038706
StartTime:0.156000   DurationTime:0.038706
StartTime:0.164000   DurationTime:0.038706
......
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: