У меня есть файл журнала, написанный несколькими экземплярами скрипта cgi. Мне нужно извлечь определенную информацию, с помощью следующего типового рабочего процесса:grep через файл условно в обоих направлениях
- поиска первого вхождения
RequestString
- экстракта PID из этой строки журнала
- поиска в обратном направлении для первого вхождения
PID<separator>ConnectionString
, чтобы идентифицировать клиент, который инициировал запрос - сделать что-то с
ConnectionString
и повторить поиск с после того, как «» RequestString
Каков наилучший способ сделать это? Я подумывал написать сценарий perl, чтобы сделать это с помощью кэширования последних строк N
, а затем выполнить соответствующие линии для выполнения 3.
Есть ли лучший способ сделать это? Как расширенное регулярное выражение, которое будет делать именно это?
Образец с номерами строк для справки - не часть файла:
1 date pid1 ConnectionString1
2 date pid2 ConnectionString2
3 date pid3 ConnectionString3
4 date pid2 SomeOutput2
5 date pid2 SomeOutput2
6 date pid4 ConnectionString4
7 date pid3 SomeOutput3
8 date pid4 RequestString4
9 date pid1 SomeOutput1
10 date pid1 ConnectionString1
11 date pid1 RequestString1
12 date pid5 RequestString5
Когда я Grep через этот файл образца, я хотел бы для следующего, чтобы соответствовать:
- линии 8, в паре с линией 6
- линии 11, в паре с линией 10 (а не с линии 1)
Sp ecifically, следующие не должны быть согласованы:
- строка 12, потому что нет соответствия ConnectionString с этим PID не найден (pid5)
- линия 1, потому что это новый ConnectionString для этого PID до следующего RequestString для этого pid (строка 10). Представьте себе, что первая попытка подключения завершилась неудачно, прежде чем регистрировать RequestString)
- любая из строк из pid2/pid3, потому что он не имеет регистрацию RequestString.
Возможно, я мог бы написать регулярное выражение с опцией. для соответствия \ n: ((pid\d)\s*(ConnectionString\d))(?!\1).*\2\s*RequestString\d
, а затем используйте \3
для идентификации клиента.
Однако, есть непропорционально больше (возможно, от 1000 до 10000 раз больше) ConnectionString
s, чем RequestString
с, так что моя интуиция была первым идти на RequestString
, а затем вернуться назад.
Я думаю, что я мог бы играть с (? <) для lookbehind, но длины между ConnectionString
и RequestString
s по существу произвольны - это будет хорошо работать?
Пожалуйста, покажите пример файла. –