![从日志文件中提取不包含禁用行的查询](https://linux22.com/image/17630/%E4%BB%8E%E6%97%A5%E5%BF%97%E6%96%87%E4%BB%B6%E4%B8%AD%E6%8F%90%E5%8F%96%E4%B8%8D%E5%8C%85%E5%90%AB%E7%A6%81%E7%94%A8%E8%A1%8C%E7%9A%84%E6%9F%A5%E8%AF%A2.png)
我有一个类似于以下内容的日志文件:
query1 startQuery
query1 do something
query1 do something else
query2 startQuery
query1 do something banned
query2 do something
query3 startQuery
query2 endQuery 1000
query3 something else to do
query1 endQuery 2003
query3 do something
query4 startQuery
query4 endQuery 100
query3 endQuery 1434
我发现运行时间最长的查询:
> grep "endQuery" logfile | awk '{print $3 " " $1}' | sort -nr | head -n 3
2003 query1
1434 query3
1000 query2
但是,已知某些操作很长,我想找到运行时间最长的查询不要包括这些操作。例如,我想找到运行时间最长的查询,这些查询在任何日志行中都不包含“banned”一词。
在此示例中,它将输出:
1434 query3
1000 query2
100 query4
实际上,这些日志文件很大并且包含大量查询。
答案1
grep
首先,请注意,顺便说一句,您不需要对 的调用:它可以无缝集成到awk
调用中。
<logfile awk '/endQuery/ {print $3 " " $1}'
您可以在 awk 阶段过滤掉禁止的查询。将正在进行的查询存储在数组中,如果被禁止则将其删除,并且仅打印非禁止的查询。
<logfile awk '
$2 == "startQuery" {q[$1]=1} # store the names of active queries
q[$1] && /banned/ {delete q[$1]} # delete banned queries
$2 == "endQuery" {
if (q[$1]) print $3, $1; # only report non-banned queries
delete q[$1];
}
' | sort -nr | head -n 3
答案2
我已经设法制定以下内容:
diff <(grep "endQuery" logfile | awk '{print $1}') \
<(grep "banned" logfile | awk '{print $1}') | \
grep "<" | awk '{print $2}' | xargs -I{0} grep "{0} endQuery" logfile | \
awk '{print $3 " " $1}' | sort -nr | head -n3
1434 query3
1000 query2
100 query4
但是,它需要对日志文件进行 3 次 grep,这对于大型日志文件来说可能会很昂贵。