awk/regex:解析错误日志并不总是返回错误描述

awk/regex:解析错误日志并不总是返回错误描述,regex,linux,unix,awk,Regex,Linux,Unix,Awk,我最近请求帮助从一组日志文件中解析出Java错误堆栈,并在下面的链接中得到了一个非常好的解决方案(使用awk) 我在回答的问题上做了标记,经过一些调试和研究,我发现了一些潜在的问题,因为它们与我最初的问题无关,但由于我对awk和正则表达式的理解有限,我认为最好问一个新问题 以下是解决方案: BEGIN{ OFS="," } /[[:space:]]+*<Error / { split("",n2v) while ( match($0,/[^[:space:]]+="[^"

我最近请求帮助从一组日志文件中解析出Java错误堆栈,并在下面的链接中得到了一个非常好的解决方案(使用awk)

我在回答的问题上做了标记,经过一些调试和研究,我发现了一些潜在的问题,因为它们与我最初的问题无关,但由于我对awk和正则表达式的理解有限,我认为最好问一个新问题

以下是解决方案:

BEGIN{ OFS="," }
/[[:space:]]+*<Error / {
    split("",n2v)
    while ( match($0,/[^[:space:]]+="[^"]+/) ) {
        name = value = substr($0,RSTART,RLENGTH)
        sub(/=.*/,"",name)
        sub(/^[^=]+="/,"",value)
        $0 = substr($0,RSTART+RLENGTH)
        n2v[name] = value
    print name value
    }
    code = n2v["ErrorCode"]
    desc[code] = n2v["ErrorDescription"]
    count[code]++
    if (!seen[code,FILENAME]++) {
        fnames[code] = (code in fnames ? fnames[code] ", " : "") FILENAME
    }
}
END {
    print "Count", "ErrorCode", "ErrorDescription", "Files"
    for (code in desc) {
        print count[code], code, desc[code], fnames[code]
    }
}
但此错误描述未出现在结果中(从实际日志文件复制的描述):

这一条也没有:

ErrorDescription="Cannot Find Person For Given Order."
大多数错误描述似乎不是由该脚本返回的,而是存在于日志文件中。我不明白为什么会出现一些错误描述,而有些则不会。有人有什么想法吗

编辑1:

下面是我正在分析的XML示例:

    <Errors>
        <Error ErrorCode="ERR_0139"
            ErrorDescription="Cannot Find Person For Given Order." ErrorMoreInfo="">
    ...
    ...
</Error>
    </Errors>

...
...

此正则表达式仅与错误描述匹配

ErrorDescription="(.+?)"
它使用捕获组来记住您的错误描述

ErrorDescription="(.+?)"

演示(根据您的编辑和以前的问题错误日志进行测试。)脚本中的模式与您的数据不匹配:

/[[:space:]]+*<Error / {

你能提供你的错误日志样本吗?使用正则表达式解析XML可能是一场噩梦。请查看编辑-相关XML已发布。我猜这是因为在您的示例中,
ErrorDescription=…
被拆分到不同的行,而不是初始的
@twalberg是正确的。在将问题发布到真正代表您真实输入的所有风格的输入时,这一点非常重要,特别是在可能出现换行的情况下。除非您的XML非常严格地符合某些特定的限制性格式,否则您需要一个XML解析器。@twalberg,这似乎确实是个问题。我的道歉-我对所有这些都是新手,我不认为会有什么不同,所以我没有发布我所有的例子(这些日志的大小总计为GB)。如果使用XML解析器是一种更好的方法,那么您是否有比上面更好的解决方案,或者是否有方法修复上面的解决方案以查看下一行的错误描述?不幸的是,我无法控制如何将错误写入日志。
/[[:space:]]+*<Error / {
/^[[:space:]]*ErrorDescription[[:space:]]*=[[:space:]]*".*"/