你好,我需要解析日志。我有一个问题,当日志有多行(以防出错)例如:如果没有错误
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
}
}