解析ns2跟踪文件

时间:2011-12-01 04:32:20

标签: regex bash parsing awk ns2

我正在使用NS 2.35并且正在尝试确定路由算法的端到端延迟。

我认为任何具有良好脚本编写经验的人都应该能够回答这个问题,遗憾的是那个人不是我。

我有一个跟踪文件,看起来像这样:

- -t 0.548 -s 2 -d 7 -p cbr -e 500 -c 0 -i 1052 -a 0 -x {2.0 17.0 6 ------- null}
h -t 0.548 -s 2 -d 7 -p cbr -e 500 -c 0 -i 1052 -a 0 -x {2.0 17.0 -1 ------- null}
+ -t 0.55 -s 2 -d 7 -p cbr -e 500 -c 0 -i 1056 -a 0 -x {2.0 17.0 10 ------- null}
+ -t 0.555 -s 2 -d 7 -p cbr -e 500 -c 0 -i 1057 -a 0 -x {2.0 17.0 11 ------- null}
r -t 0.556 -s 2 -d 7 -p cbr -e 500 -c 0 -i 1047 -a 0 -x {2.0 17.0 1 ------- null}
+ -t 0.556 -s 7 -d 12 -p cbr -e 500 -c 0 -i 1047 -a 0 -x {2.0 17.0 1 ------- null}
- -t 0.556 -s 7 -d 12 -p cbr -e 500 -c 0 -i 1047 -a 0 -x {2.0 17.0 1 ------- null}

但这是我需要做的。

+开头的行是将新数据包添加到网络的时间。 以r开头的行是目的地收到数据包的时间。 -t之后的双键数字是该事件发生的时间。最后,在-i是数据包的标识之后。

为了计算平均端到端延迟,我需要找到-i之后具有特定id的每一行。从那里我需要计算r的时间戳减去+的时间戳

所以我认为可能有一个由空格分隔的正则表达式。我可以将每个部分放入自己的变量中。然后我会检查第15个(包ID)。

但我不知道从那里去哪里,或者如何把它们放在一起。

我知道网上有一些AWK脚本用于执行此操作,但它们都已过时且不符合当前格式(我不知道如何更改它们)。

非常感谢任何帮助。

编辑:

以下是我要查找的完整数据包路由的示例。 我在这些之间取出了很多行,这样你就可以看到一个包事件。

# a packet is enqueued from node 2 going to node 7. It's ID is 1636. this was at roughly 1.75sec 
+ -t 1.74499999999998 -s 2 -d 7 -p cbr -e 500 -c 0 -i 1636 -a 0 -x {2.0 17.0 249 ------- null}
# at 2.1s, it left node 2. 
- -t 2.134 -s 2 -d 7 -p cbr -e 500 -c 0 -i 1636 -a 0 -x {2.0 17.0 249 ------- null}
# at 2.134 it hopped from 2 to 7 (not important)
h -t 2.134 -s 2 -d 7 -p cbr -e 500 -c 0 -i 1636 -a 0 -x {2.0 17.0 -1 ------- null}
# at 2.182 it was received by node 7
r -t 2.182 -s 2 -d 7 -p cbr -e 500 -c 0 -i 1636 -a 0 -x {2.0 17.0 249 ------- null}
# it was the enqueued by node 7 to be sent to node 12
+ -t 2.182 -s 7 -d 12 -p cbr -e 500 -c 0 -i 1636 -a 0 -x {2.0 17.0 249 ------- null}
# slightly later it left node 7 on its was to node 12
- -t 2.1832 -s 7 -d 12 -p cbr -e 500 -c 0 -i 1636 -a 0 -x {2.0 17.0 249 ------- null}
# it hopped from 7 to 12 (not important)
h -t 2.1832 -s 7 -d 12 -p cbr -e 500 -c 0 -i 1636 -a 0 -x {2.0 17.0 -1 ------- null}
# received by 12
r -t 2.2312 -s 7 -d 12 -p cbr -e 500 -c 0 -i 1636 -a 0 -x {2.0 17.0 249 ------- null}
# added to queue, heading to node 17
+ -t 2.2312 -s 12 -d 17 -p cbr -e 500 -c 0 -i 1636 -a 0 -x {2.0 17.0 249 ------- null}
# left for node 17
- -t 2.232 -s 12 -d 17 -p cbr -e 500 -c 0 -i 1636 -a 0 -x {2.0 17.0 249 ------- null}
# hopped to 17 (not important)
h -t 2.232 -s 12 -d 17 -p cbr -e 500 -c 0 -i 1636 -a 0 -x {2.0 17.0 -1 ------- null}
# received by 17 notice the time delay
r -t 2.28 -s 12 -d 17 -p cbr -e 500 -c 0 -i 1636 -a 0 -x {2.0 17.0 249 ------- null}

脚本的理想输出会将2.134识别为开始时间,将2.28识别为结束,然后给出0.146秒的延迟。它会对所有数据包ID执行此操作,并仅报告平均值。

有人要求我扩展一下文件的工作方式,以及我期待的内容。

该文件列出了大约10,000个数据包的描述。每个数据包可以处于不同的状态。重要状态为+,表示数据包已在路由器中排队,r表示数据包已被其目的地接收。

可能没有实际接收排队的数据包(因此+条目),而是被丢弃。这意味着我们不能假设每个+条目都会有一个r条目。

我想要衡量的是平均端到端延迟。这意味着,如果你看一个数据包,它将有一个排队的时间,以及它收到的时间。我需要进行此计算以找到其端到端延迟。但我还需要为9,999个其他数据包做到这一点以获得平均值。

我已经考虑过了更多,并且通常认为算法需要如何工作。

  • 删除所有不以+r开头的行,因为它们并不重要。
  • 遍历所有数据包ID(即-i之后的数字,例如示例中的1052),并将它们放入某种类别(可能是多个数组)。
  • 每个组现在应该包含有关特定数据包的所有信息。
  • 在组内,检查是否有+,理想情况下我们想要第一个+。记录它的时间。
  • 寻找更多+行。看看他们的时间。日志可能有点混乱。因此,稍后可能存在+行,这实际上是模拟中的早期。
  • 如果此新+行的时间较早,请使用该行更新时间变量。
  • 假设不再有+行,请查找r行。
  • 如果没有r行,则丢弃数据包,所以不要担心。
  • 对于您找到的每条r行,我们需要做的就是找到具有最新时间戳的人
  • 具有最新时间戳的r行是最终收到数据包的位置。
  • +时间减去r时间,这为我们提供了数据包传输所需的时间。
  • 将此值添加到数组中,以便以后可以对其进行平均。
  • 在每个数据包ID组上重复此过程,然后最终平均所创建的延迟数组。

这很多打字,但我认为它很清楚,因为我可以在我想要的东西。我希望我是一个正则表达式的主人,但我没有时间去学习它,以便将其拉下来。

感谢您的帮助,如果您有任何疑问,请与我们联系。

1 个答案:

答案 0 :(得分:3)

在这里没有多少工作,正如Iain在你的问题的评论中所说,但如果我明白你想要做什么,这样的事情应该有效:

awk '/^[+r]/{$1~/r/?r[$15]=$2:r[$15]?d[$15]=r[$15]-$2:1} END {for(p in d){sum+=r[p];num++}print sum/num}' trace.file

它跳过所有不以'+'或'r'开头的行。如果该行以'r'开头,则会为r数组增加时间。否则,它计算延迟并将其添加到d数组(如果在r数组中找到该元素)。最后,它遍历d数组中的元素,将总延迟和元素数相加,并从中计算平均值。在您的情况下,平均值为0.

主要块末尾的:1就在那里,所以我可以使用三元表达式而不是明显更详细的if语句。

编辑:使用添加条件的新表达式:

awk '/^[+r]/{$1~/r/?$3>r[$15]?r[$15]=$3:1:!a[$15]||$3<a[$15]?a[$15]=$3:1} END {for(i in r){sum+=r[i]-a[i];num++}print "Average delay", sum/num}'

或作为awk文件

/^[+r]/ {
  if ($1 ~ /r/) {
    if ($3 > received[$15])
      received[$15] = $3;
  } else {
    if (!added[$15] || $3 < added[$15])
      added[$15] = $3;
  }
} END {
  for (packet in received) {
    sum += received[packet] - added[packet];
    num++
  }
  print "Average delay", sum/num
}

根据你的算法,似乎1.745将是开始时间,而你写的是2.134。