不带最后一个字符的多行日志解析



你好,我需要解析日志。我有一个问题,当日志有多行(以防出错)例如:如果没有错误

Last error code [0], message [No errors encountered.]

If转换错误

Last error code [8425], message [ERROR: Writer execution failed. 
Database error: [0] [
FnName: Execute -- [DataDirect][ODBC SQL Server Wire Protocol driver][Microsoft SQL Server]Conversion failed when converting the varchar value 'amica' to data type int., SQLSTATE [22005]
FnName: Execute -- [DataDirect][ODBC lib] Function sequence error, SQLSTATE [S1010]]]

我需要得到[]之间的log

根据第一个例子,它应该是:

No errors encountered.

根据第二个例子,它应该是:

ERROR: Writer execution failed. Database error: [0] [FnName: Execute -- [DataDirect][ODBC SQL Server Wire Protocol driver][Microsoft SQL Server]Conversion failed when converting the varchar value 'amica' to data type int., SQLSTATE [22005]FnName: Execute -- [DataDirect][ODBC lib] Function sequence error, SQLSTATE [S1010]]

我正在用awk写我的脚本。有可能使用正则表达式做到这一点吗?我不熟悉正则表达式,但我尝试过这样的东西

(?<=, message [).+n

但是它不工作的日志有很多行,我不知道如何切断最后一个字符"]">

对于强制POSIX工具(例如sed和awk)使用的BRE或ERE是不可能的,但是使用其他工具(例如perl)使用PCRE可能是可能的,我真的不知道这一点,因为我从未使用过PCRE。

你总是可以通过计算[]来强制执行它,例如,在每个Unix机器的任何shell中使用任何awk:

$ cat tst.awk
{ rec = (NR>1 ? rec RS : "") $0 }
END {
numChars = length(rec)
for (charNr=1; charNr<=numChars; charNr++) {
char = substr(rec,charNr,1)
if ( char == "[" ) {
if ( ++depth == 1 ) {
str = ""
}
}
str = str char
if ( char == "]" ) {
if ( --depth == 0 ) {
if ( ++numStrs % 2 == 0 ) {
gsub(/^[|]$|n/,"",str)
print str
}
}
}
}
}

$ awk -f tst.awk file
No errors encountered.
ERROR: Writer execution failed. Database error: [0] [FnName: Execute -- [DataDirect][ODBC SQL Server Wire Protocol driver][Microsoft SQL Server]Conversion failed when converting the varchar value 'amica' to data type int., SQLSTATE [22005]FnName: Execute -- [DataDirect][ODBC lib] Function sequence error, SQLSTATE [S1010]]

上面的代码必须立即将整个输入文件读入内存。您也可以保留一个滚动缓冲区,将输入行读入其中,并在每次输出str - left后进行重置,作为练习!

用于测试上述内容的输入文件是:
$ cat file
Last error code [0], message [No errors encountered.]
Last error code [8425], message [ERROR: Writer execution failed.
Database error: [0] [
FnName: Execute -- [DataDirect][ODBC SQL Server Wire Protocol driver][Microsoft SQL Server]Conversion failed when converting the varchar value 'amica' to data type int., SQLSTATE [22005]
FnName: Execute -- [DataDirect][ODBC lib] Function sequence error, SQLSTATE [S1010]]]

这里是一个awk脚本:

{
# Count open and close brackets
line = $0
nb_open = gsub(/[/, "x", line)
line = $0
nb_close = gsub(/]/, "x", line)
}
inError == 0 && nb_open == nb_close {
# not in a block and brackets are balanced
errorLine = ""
print "No errors encountered."
next
}
inError == 0 && nb_open != nb_close {
# not in a block and brackets are unbalanced
inError = 1
errorLine = $0
# remove error header
gsub(/^.*, message [ERROR: /, "ERROR:", errorLine)
# initialize total counters
nb_open_tot = nb_open
nb_close_tot = nb_close
next
}
{
# in a block, add brackets to the total counters
nb_open_tot  += nb_open
nb_close_tot += nb_close
# add the current line to the future error line
errorLine = errorLine " " $0
}
inError == 1 && nb_open_tot != nb_close_tot {
# continue (current line already added)
next
}
inError == 1 && nb_open_tot == nb_close_tot {
# remove close bracket
gsub(/]$/, "", errorLine)
# print error line
print errorLine
# reset variables
errorLine    = ""
nb_open_tot  = 0
nb_close_tot = 0
inError      = 0
next
}
END {
# End of block not found ?
if (errorLine) {
print errorLine
}
}

最新更新