以下是我的日志。
2011-03-10 20:34:16,657 INFO [jdbc.sqlonly]
SELECT COL1
, COL2 -- some comments may be here
, COL3
FROM TABLE_A
WHERE COL4 = 'some_text'
/* [related.classname] : some comments go here */
2011-03-10 20:34:16,658 DEBUG [another.class.name] blahblah
.
.
.
2011-03-10 20:34:16,843 INFO [jdbc.sqlonly]
SELECT MAX(COL_A)
FROM TABLE_B
WHERE COL_T < CURRENT_TIMESTAMP
/* [other.classname] : some comments go here */
2011-03-10 20:34:16,844 DEBUG [other.class.name2] blahblah
.
.
我想用tail -f命令grep这个查询,并捕获ONLY related.classname。 因为每个查询都包含换行符,所以使用grep命令是没有用的。 我怎样才能做到这一点? 我关注使用sed的可能命令,如下所示。
tail -f some.log | sed -n '/jdbc\.sqlonly/,/2011-03-10 /p'
它可以帮助只查找查询,而不是调试日志,但没有捕获关联的类名(related.classname)。 Plz帮助我。啊,我的服务器是AIX。
答案 0 :(得分:1)
Awk非常适合这类任务。从根本上说,awk脚本一次处理一行,但允许您在处理每一行时修改/读取全局变量。要将awk应用于此问题,您可以创建一个迷你状态机,记住在日志条目“内部”处理行并在“匹配”条目中打印所需的任何信息。
这是一个awk程序示例。 BEGIN
块在处理任何输入之前执行一次,而主块每行执行一次 - $0
包含整行内容。
BEGIN{
inmatch=0
last=""
}
{
if(match($0,"INFO|DEBUG")){
if(inmatch){
print last
}
inmatch=0
}
if(match($0,"jdbc\.sqlonly")){
inmatch=1
}
last=$0
}
此脚本打印以包含jdbc.sqlonly
的行开头的每个日志条目的最后一行。新日志条目的开头定义为包含INFO
或DEBUG
的任何行。 match()函数的正则表达式参数可以很容易地调整。要运行脚本,请将其存储在文件中并按如下方式调用:
$ cat log.file | awk -f script.awk
/* [related.classname] : some comments go here */
/* [other.classname] : some comments go here */
“扔掉”或单行awk脚本也可以在命令行中构建,这对于不能证明功能齐全的脚本语言的临时解决方案很方便。
$ cat test.file | awk 'BEGIN{inmatch=0;last=""}{if(match($0,"INFO|DEBUG")){if(inmatch){print last}inmatch=0} if(match($0,"jdbc\.sqlonly")){inmatch=1}last=$0}'
/* [related.classname] : some comments go here */
/* [other.classname] : some comments go here */
答案 1 :(得分:0)
对于我使用的sed,range命令似乎是贪婪的,并且与最后一个日期匹配。
你可以egrep'INFO | DEBUG'并根据需要操纵它。
我希望这会有所帮助。
P.S。因为您似乎是新用户,如果您得到的答案可以帮助您,请记住将其标记为已接受,或者给它一个+(或 - )作为有用的答案
答案 2 :(得分:0)
这是我使用它的那个......
tail -F yourLog.log | sed -nr ':main; /^2011.*sql/ { :loop; p; n; /^2011/ b main; b loop} '
这里2011是每个日志行的模式。 sql是我要搜索的单词。