我有一个cgi脚本的几个实例写的日志文件。我需要提取某些信息,具有以下典型工作流程:
RequestString
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
当我浏览此示例文件时,我希望以下内容匹配:
具体而言,不应匹配以下内容:
我可以想象用正版选项编写正则表达式。匹配\ n:((pid\d)\s*(ConnectionString\d))(?!\1).*\2\s*RequestString\d
,然后使用\3
来识别客户端。
然而,ConnectionString
的{{1}}比RequestString
更多(可能在1000到10000倍之间),所以我的直觉是首先选择RequestString
然后回溯。
我想我可以使用(?&lt;)进行后视,但ConnectionString
和RequestString
之间的长度基本上是任意的 - 这样会有效吗?
答案 0 :(得分:1)
这些方面的东西:
#!/bin/bash
# Find and number all RequestStrings, then loop through them
grep -n RequestString file | while IFS=":" read n string; do
echo $n,$string # Debug
head -n $n file | tail -r | grep -m1 Connection
done
<强>输出强>
4,RequestString 1
6189:Connection
7,RequestString 2
7230:Connection
9,RequestString 3
8280:Connection
使用此输入文件
6189:Connection
RequestString 1
7229:Connection
7230:Connection
RequestString 2
8280:Connection
RequestString 3
注意:我使用了tail -r
,因为OSX缺少tac
,我更喜欢这样做。