【发布时间】:2012-04-29 15:17:53
【问题描述】:
我有 HTTP 标头请求并以制表符分隔的形式回复数据,每个 GET/POST 并在不同的行中回复。该数据使得一个 TCP 流有多个 GET、POST 和 REPLY。我只需要从这些案例中选择第一个有效的 GET - REPLY 对。一个例子(简化)是:
ID Source Dest Bytes Type Content-Length host lines....
1 A B 10 GET NA yahoo.com 2
1 A B 10 REPLY 10 NA 2
2 C D 40 GET NA google.com 4
2 C D 40 REPLY 20 NA 4
2 C D 40 GET NA google.com 4
2 C D 40 REPLY 30 NA 4
3 A B 250 POST NA mail.yahoo.com 5
3 A B 250 REPLY NA NA 5
3 A B 250 REPLY 15 NA 5
3 A B 250 GET NA yimg.com 5
3 A B 250 REPLY 35 NA 5
4 G H 415 REPLY 10 NA 6
4 G H 415 POST NA facebook.com 6
4 G H 415 REPLY NA NA 6
4 G H 415 REPLY NA NA 6
4 G H 415 GET NA photos.facebook.com 6
4 G H 415 REPLY 50 NA 6
....
所以,基本上我需要为每个 ID 获取一个请求-回复对并将它们写入一个新文件。
对于“1”,它只是一对,所以很容易。 但也有两行都是 GET、POST 或 REPLY 的错误情况。所以,这种情况被忽略了。
对于“2”,我会选择第一个 GET - REPLY 对。
对于“3”,我会选择第一个 GET 但第二个 REPLY,因为第一个中没有 Content-Length(使 subsequest REPLY 成为更好的候选者)。
对于“4”,我会选择第一个 POST(或 GET),因为第一个标头无法回复。即使 POST 之后的内容长度缺失,我也不会在第二个 GET 之后选择 REPLY,因为 REPLY 在那之后。所以我会选择第一个回复。
因此,在选择了最佳请求和回复对后,我需要将它们配对在一行中。例如,输出将是:
ID Source Dest Bytes Type Content-Length host ....
1 A B 10 GET 10 yahoo.com
2 C D 40 GET 20 google.com
3 A B 250 POST 15 mail.yahoo.com
4 G H 415 POST NA facebook.com
实际数据中还有很多其他标题,但这个示例几乎显示了我需要的内容。在 Perl 中如何做到这一点?我几乎一开始就被卡住了,所以我一次只能读取一行文件。
open F, "<", "file.txt" || die "Cannot open $f: $!";
while (<F>) {
chomp;
my @line = split /\t/;
# get the valid pairs for cases with multiple request - replies
# get the paired up data together
}
close (F);
*编辑:我添加了一个额外的列,给出了每个 ID 的 HTTP 标题行数。这可能有助于了解要检查多少后续行。另外,我修改了 ID '4',以便第一个标题行是回复。 *
【问题讨论】:
-
+1 了解所需内容的详细说明。谢谢!
-
ID 是否足以识别要处理的行组?如果是这样,那么在 ID 内,我们可以假设源和目标是相同的吗?
-
@JonathanLeffler 是的,这就足够了,因为它代表了一个具有相同源和目标、端口等的 TCP 流。所以,我需要为每个 ID 创建一个请求-回复对,如图所示。
-
我们可以假设单个 ID 的行是连续的吗?即当 ID 从 1 变为 2 时,是否保证不再有 ID 为 1 的行?
-
@cjm 是的,所有具有相同 ID 的行都分组在一起。
标签: perl http multiline file-manipulation