У меня есть запрос HTTP-заголовка и данные ответа в форме с разделителями табуляции с каждым GET/POST и ответом в разных строках. Эти данные таковы, что существует несколько GET, POST и REPLY для одного потока TCP. Из этих случаев мне нужно выбрать только первую действительную пару GET-REPLY. Пример (упрощенный) является:Perl находит правильные пары линий между различными случаями
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 отсутствует в первом (что делает более подходящим кандидатом).
Для «4» я выбрал бы первый POST (или GET), поскольку первый заголовок не может ОТКАЗАТЬСЯ. Я бы не выбрал REPLY после второго GET, даже если длина содержимого отсутствует в сообщениях после POST., После чего появляется 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);
* Edit: я добавил дополнительный столбец дает количество HTTP заголовков для каждого идентификатора. Это может помочь узнать, сколько последующих строк необходимо проверить. Кроме того, я изменил ID '4', так что первая строка заголовка - REPLY. *
+1 за подробное объяснение того, что нужно. Спасибо! –
Является ли идентификатор достаточным для идентификации группы строк, подлежащих обработке? Если да, то внутри идентификатора мы можем предположить, что источник и пункт назначения одинаковы? –
@JonathanLeffler Да, этого достаточно, поскольку он представляет один поток TCP с такими же исходными и конечными точками, порты и т. Д. Поэтому мне нужно создать одну пару «запрос-ответ» для каждого идентификатора, как показано. – sfactor