我试图使用AWK解析日志文件,
test.log
[12/12/18 11:54:54:321 PST] 0000077c WC_SERVER < com.ibm.commerce.server.HttpRequestWrapper setAttribute(String,Object) Exit
[12/12/18 11:54:54:328 PST] 0000077c WC_BUSINESSCO < -1112ef1b:16732963f15:-7fd4 com.ibm.commerce.component.contextserviceimpl.BusinessContextServiceImpl.createContextSPI(ActivityToken, ActivityData, String) Exit
com.ibm.commerce.context.base.BaseContext : [bInitialize = false][bRecalibrate = false][inCallerId = null][inRunAsId = null][inStoreId = null][istrChannelId = null][bDirty = false][bRequestStarted = false][iOriginalSerializedString = null][iToken = null]
[12/12/18 11:54:54:328 PST] 0000077c WC_BUSINESSCO > -1112ef1b:16732963f15:-7fd4 com.ibm.commerce.component.contextserviceimpl.BusinessContextServiceImpl.loadContextData(ActivityToken, String) Entry
68884:false:false:0
com.ibm.commerce.context.base.BaseContext
[12/12/18 11:54:54:328 PST] 0000077c WC_BUSINESSCO > -1112ef1b:16732963f15:-7fd4 com.ibm.commerce.component.contextservice.commands.ContextDataSerValueCacheCmdImpl.myPerformExecute() Entry
68884
想法是,如果一行以[
开头,并且与模式匹配,则打印出该行以及不以[
开头的下一行。
预期结果:
[12/12/18 11:54:54:328 PST] 0000077c WC_BUSINESSCO < -1112ef1b:16732963f15:-7fd4 com.ibm.commerce.component.contextserviceimpl.BusinessContextServiceImpl.createContextSPI(ActivityToken, ActivityData, String) Exit
com.ibm.commerce.context.base.BaseContext : [bInitialize = false][bRecalibrate = false][inCallerId = null][inRunAsId = null][inStoreId = null][istrChannelId = null][bDirty = false][bRequestStarted = false][iOriginalSerializedString = null][iToken = null]
[12/12/18 11:54:54:328 PST] 0000077c WC_BUSINESSCO > -1112ef1b:16732963f15:-7fd4 com.ibm.commerce.component.contextserviceimpl.BusinessContextServiceImpl.loadContextData(ActivityToken, String) Entry
68884:false:false:0
com.ibm.commerce.context.base.BaseContext
[12/12/18 11:54:54:328 PST] 0000077c WC_BUSINESSCO > -1112ef1b:16732963f15:-7fd4 com.ibm.commerce.component.contextservice.commands.ContextDataSerValueCacheCmdImpl.myPerformExecute() Entry
68884
AWK:
awk 'BEGIN{IGNORECASE = 1; flag = 0;}{ if($0 ~ /^\[/){if($0 ~ /WC_BUSINESSCO/){flag=1}else{flag = 0}; if(flag==1){print $0}}}' test.log
当前输出:
[12/12/18 11:54:54:328 PST] 0000077c WC_BUSINESSCO < -1112ef1b:16732963f15:-7fd4 com.ibm.commerce.component.contextserviceimpl.BusinessContextServiceImpl.createContextSPI(ActivityToken, ActivityData, String) Exit
[12/12/18 11:54:54:328 PST] 0000077c WC_BUSINESSCO > -1112ef1b:16732963f15:-7fd4 com.ibm.commerce.component.contextserviceimpl.BusinessContextServiceImpl.loadContextData(ActivityToken, String) Entry
[12/12/18 11:54:54:328 PST] 0000077c WC_BUSINESSCO > -1112ef1b:16732963f15:-7fd4 com.ibm.commerce.component.contextservice.commands.ContextDataSerValueCacheCmdImpl.myPerformExecute() Entry
您会看到未打印以[
开头的行;经过调试后,AWK似乎认为问题行是部分或模式匹配行。我猜是因为包装问题没有打印出来。
我该如何解决?
答案 0 :(得分:3)
你在做。
awk '/^\[/{p=/WC_BUSINESSCO/}p' test.log
/^\[/
表示如果当前记录以{...}
开头,请执行以下操作([
)p=/WC_BUSINESSCO/
,p
将WC_BUSINESSCO
设置为true,反之亦然,p
结尾意味着如果p
为true,则打印当前记录。[
开头,则上一个行中的p
值仍然保留。有关更多信息,请参见man awk
。
为清楚起见,请增加一些空白:
awk '
/^\[/ { p = /WC_BUSINESSCO/ }
p
' test.log
答案 1 :(得分:2)
awk如何定义行?
Awk不知道行是什么。 Awk知道 records 和 fields 的概念。
文件被拆分为 records ,其中连续记录由记录分隔符RS
拆分。每个记录都分为多个字段,其中连续的字段由字段分隔符FS
分隔。
默认情况下,记录分隔符RS
设置为\n
),因此每个记录都是一行。记录分隔符具有以下定义:
RS
: 字符串值RS
的第一个字符应为输入记录分隔符;默认情况下为。如果 RS
包含多个字符,则结果不确定。如果RS
为空,则记录由由加上一个或多个空行组成的序列分隔,开头或结尾的空行在输入的开头或结尾不应导致空记录,并且不管 FS
的值是什么,都应该始终是字段分隔符。
我现在如何定义多行记录?
对于不能由单个字符唯一标识记录开始的多行记录,您可能要使用gawk
或RS
可以是多个字符的任何awk版本(或正则表达式)。对于OP,您可以将RS
定义为\n\[
:
awk 'BEGIN { RS="\n\[" }/WC_BUSINESSCO/ { print (NR==1 ? "" : "[") $0 }' file
如果您无权访问此类版本的awk,并且必须坚持使用POSIX,则可以执行以下操作:
awk '/^\[/ && (rec ~ /WC_BUSINESSCO/) { printf rec; } # process record
/^\[/ { rec="" } # initialise record
{ rec = rec $0 ORS } # build record
END { if (rec ~ /WC_BUSINESSCO/) printf rec } # process last record
' file
这将与完整记录中的“ WC_BUSINESSCO”匹配,而不仅仅是大多数解决方案中的第一行。对于OP,第一行可能就足够了。更一般的问题可能与此有关。
答案 2 :(得分:1)
您说的是:然后打印出该行,并打印以下行 。
尝试以下方法:
awk '/^\[.*WC_BUSINESSCO/{print;getline;print}' test.log
当模式匹配时,流程非常简单,打印一行,获取下一行并再次打印。
要获取以[
开头的行之后的所有行:
awk '/^\[/{i=0}/WC_BUSINESSCO/{i=1}i' test.log
选中this。
答案 3 :(得分:1)
使用GNU-awk
,您可以根据指定的内容定义记录分隔符
$ awk -v RS='(^|\n)\\[' '/WC_BUSINESSCO/{print RT $0}' file
使用模式匹配打印记录(可能是多行),但记录分隔符以记录为前缀。
与其他awk
的解决方法
$ awk '/^\[/{if(/WC_BUSINESSCO/){print; p=1} else p=0} p&&!/^\[/' file
答案 4 :(得分:0)
如果您正在考虑Perl,那么这是根据您的要求的通用解决方案。 请注意,它不会为解决方案从文件中硬编码任何文本(例如WC_BUSINESSCO)。
/tmp> cat test.log
[12/12/18 11:54:54:321 PST] 0000077c WC_SERVER < com.ibm.commerce.server.HttpRequestWrapper setAttribute(String,Object) Exit
[12/12/18 11:54:54:328 PST] 0000077c WC_BUSINESSCO < -1112ef1b:16732963f15:-7fd4 com.ibm.commerce.component.contextserviceimpl.BusinessContextServiceImpl.createContextSPI(ActivityToken, ActivityData, String) Exit
com.ibm.commerce.context.base.BaseContext : [bInitialize = false][bRecalibrate = false][inCallerId = null][inRunAsId = null][inStoreId = null][istrChannelId = null][bDirty = false][bRequestStarted = false][iOriginalSerializedString = null][iToken = null]
[12/12/18 11:54:54:328 PST] 0000077c WC_BUSINESSCO > -1112ef1b:16732963f15:-7fd4 com.ibm.commerce.component.contextserviceimpl.BusinessContextServiceImpl.loadContextData(ActivityToken, String) Entry
68884:false:false:0
com.ibm.commerce.context.base.BaseContext
[12/12/18 11:54:54:328 PST] 0000077c WC_BUSINESSCO > -1112ef1b:16732963f15:-7fd4 com.ibm.commerce.component.contextservice.commands.ContextDataSerValueCacheCmdImpl.myPerformExecute() Entry
68884
/tmp> perl -ne ' print "$t$p" if $x and /^\[/ ;if(!/^\[/) { $x++;$t.=$p} if(/^\[/) { $x=0;$t=""} $p=$_;END { print "$t$p" if $x }' test.log
[12/12/18 11:54:54:328 PST] 0000077c WC_BUSINESSCO < -1112ef1b:16732963f15:-7fd4 com.ibm.commerce.component.contextserviceimpl.BusinessContextServiceImpl.createContextSPI(ActivityToken, ActivityData, String) Exit
com.ibm.commerce.context.base.BaseContext : [bInitialize = false][bRecalibrate = false][inCallerId = null][inRunAsId = null][inStoreId = null][istrChannelId = null][bDirty = false][bRequestStarted = false][iOriginalSerializedString = null][iToken = null]
[12/12/18 11:54:54:328 PST] 0000077c WC_BUSINESSCO > -1112ef1b:16732963f15:-7fd4 com.ibm.commerce.component.contextserviceimpl.BusinessContextServiceImpl.loadContextData(ActivityToken, String) Entry
68884:false:false:0
com.ibm.commerce.context.base.BaseContext
[12/12/18 11:54:54:328 PST] 0000077c WC_BUSINESSCO > -1112ef1b:16732963f15:-7fd4 com.ibm.commerce.component.contextservice.commands.ContextDataSerValueCacheCmdImpl.myPerformExecute() Entry
68884
/tmp>