Windows 如何打印AWK搜索结果中缺少的字段?

Windows 如何打印AWK搜索结果中缺少的字段?,windows,awk,Windows,Awk,我想使用AWK在Windows应用程序事件日志中搜索字符串。以下是日志摘录: W 05-Nov-14 10:09:36 261 CA_OSC <I>Process ax_be has finished without having received an explicit termination request from the component manager </I>

我想使用AWK在Windows应用程序事件日志中搜索字符串。以下是日志摘录:

W  05-Nov-14 10:09:36   261 CA_OSC          <I>Process ax_be has finished without having received an explicit termination request from the component manager    </I>
                                                                    Time: 5.11.2014, 10:09:36, Line: 1161, File: \MCom\src\OSS\compmgr\src/CaCompPCB.cpp, Process: CaGenericMain (2448)
E  05-Nov-14 10:09:36   17  AY_ISC           An error was detected in a process that is monitored by State Manager.    
                                                                    Time: 5.11.2014, 10:09:36, Process: C:\AXM\Service\bin\Rep.exe_1976,
                                                                    Text: (05.11.2014 10:09:36) IVS SET: CMonitorThread::ProcessTermination(AppBE,5452) A critical process has
W  05-Nov-14 10:09:37   261 CA_OSC          <I>Process main_ui has finished without having received an explicit termination request from the component manager    </I>
                                                                    Time: 5.11.2014, 10:09:37, Line: 1161, File: \MCom\src\OSS\compmgr\src/CaCompPCB.cpp, Process: CaGenericMain (2448)
即:找到匹配项时的日志和所有摘要行。 搜索的字符串可以在日志行或任何摘要行中。 每行由新行字符分隔,此日志文件是一个.txt文件

到目前为止,我已尝试了以下命令:

awk -v RS="\n(E|I|W)" "/ProcessTermination/" XA135420_2014_11_05_AppEventLog.txt
但结果是E | I | W缺失。我得到了这样的结果

  05-Nov-14 10:09:36    17  AY_ISC           An error was detected in a process that is monitored by State Manager.    
                                                                    Time: 5.11.2014, 10:09:36, Process: C:\AXM\Service\bin\Rep.exe_1976,
                                                                    Text: (05.11.2014 10:09:36) IVS SET: CMonitorThread::ProcessTermination(AppBE,5452) A critical process has
有人能帮我在结果中列出W | E | I(日志行的第一个字段)吗


注意:我正在Windows 7上使用GNU Awk 3.1.6。

使用Awk在内存中加载段落

awk '/^[EIW]/{if( P ~ /ProcessTermination/)print P;P=""}{P=P"\n"$0}END{if( P ~ /ProcessTermination/)print P}' XA135420_2014_11_05_AppEventLog.txt

对于字段定义,您可以使用
FPAT
而不是
FS
来定义字段内容,而不是字段分隔符,但我不知道“
RPAT

通过像您这样设置RS,您将从记录中删除与RS匹配的字符串,并使脚本特定于gawk,而这一切都不是所需要的。您可以通过保存每个
RT
值并在下一条记录之前打印来解决此问题:

$ awk -v RS='(^|\n)\\S' '/ProcessTermination/{print gensub(/^\n|\n$/,"","g",p$0)} {p=RT}' file
E  05-Nov-14 10:09:36   17  AY_ISC           An error was detected in a process that is monitored by State Manager.
                                                                    Time: 5.11.2014, 10:09:36, Process: C:\AXM\Service\bin\Rep.exe_1976,
                                                                    Text: (05.11.2014 10:09:36) IVS SET: CMonitorThread::ProcessTermination(AppBE,5452) A critical process has
gensub()
必须删除每个
RT
都以新行开头的新行,因为
RS
以新行或文件开头,并且删除文件中最后一条记录结尾的尾随新行,因为它没有后续的RS匹配来吸收它自然结束的新行

更清晰、更简单的解决方案不使用RT,并且适用于任何awk:

$ cat tst.awk
/^[WEI]/ { check() }
{ buf = buf $0 RS }
END { check() }
function check() {
    if ( index(buf,tgt) ) {
        printf "%s", buf
    }
    buf = ""
}
$
$ awk -v tgt="ProcessTermination" -f tst.awk file
E  05-Nov-14 10:09:36   17  AY_ISC           An error was detected in a process that is monitored by State Manager.
                                                                    Time: 5.11.2014, 10:09:36, Process: C:\AXM\Service\bin\Rep.exe_1976,
                                                                    Text: (05.11.2014 10:09:36) IVS SET: CMonitorThread::ProcessTermination(AppBE,5452) A critical process has

请注意,如果您确实想搜索字符串而不是regexp,请使用上面的
index()
而不是
/…/
match()

我测试您的代码sccuess。Cygwin awk 4.1.3@A-Ray:GNU awk有没有办法实现这一点?@Smij01 Cygwin awk就是GNU awk。这不是您当前问题的原因,但有一个新的问题-您的问题已经过时,您缺少许多非常有用的功能和错误修复。我们不能避免这个长命令吗?我已经有了另一个类似于你的命令:awk'{if($1~/^(E|I|W)$/{if(print|u match){print line;print|match=0}line=$0}else{line=line ORS$0}}ProcessTermination/{print|u match=1}END{if(print|u match){print line;}'XA135420|2014|11AppEventLog.txt。。。。但是我想减少一些脚本的长度
$ cat tst.awk
/^[WEI]/ { check() }
{ buf = buf $0 RS }
END { check() }
function check() {
    if ( index(buf,tgt) ) {
        printf "%s", buf
    }
    buf = ""
}
$
$ awk -v tgt="ProcessTermination" -f tst.awk file
E  05-Nov-14 10:09:36   17  AY_ISC           An error was detected in a process that is monitored by State Manager.
                                                                    Time: 5.11.2014, 10:09:36, Process: C:\AXM\Service\bin\Rep.exe_1976,
                                                                    Text: (05.11.2014 10:09:36) IVS SET: CMonitorThread::ProcessTermination(AppBE,5452) A critical process has