我有 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),因为第一个标头不能是 REPLY。即使 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',以便第一个标题行是回复。*