我在不同的行中有以下数据,这些数据将按以下顺序出现
trackingID=QsSDsad2yP80Q82G5Y8V2QRWhGQCYy97bX; ***************Some other Data ********************** Trn-status: INCOMPLETE", ***************Some other Data **********************
trackingID=QsSDsad2yP80Q82G5Y8V2QRWhGQCYy97bX; ***************Some other Data **********************
trackingID=QsSDsad2yP80Q82G5Y8V2QRWhGQCYy97bX; ***************Some other Data **********************:{\"details\":[{\"errorCode\":\"MyErrorCode\",\"message\":\"TECHNICAL EXCEPTION\",\"timeStamp\":\"2019-10-03T09:08:56.886Z\"}],***************Some other Data **********************
trackingID=E32878dfgdf45ddf567u5V2QRsdfdsj657V; ***************Some other Data **********************:{\"details\":[{\"errorCode\":\"Test0001\",\"message\":\"Valiadtion EXCEPTION\",\"timeStamp\":\"2019-10-03T09:08:56.886Z\"}],***************Some other Data **********************
这些行不是后续行,这些行之间可能还有其他数据。
我想提取 errorCode 属性的值,如果 的message
值为TECHNICAL EXCEPTION
和 Trn-status
正在INCOMPLETE
使用 Unix/linux 命令。(想要提取所有匹配行对的数据,即使有多对)
两条线路具有相同的trackingID
我是 Unix/Linux 新手,您能帮我从命令中获取错误代码吗?
答案1
你可以用awk
这个:
假设Trn-status
总是出现在前面TECHNICAL EXCEPTION
awk -F'[\;\=]' '
{ if ( $0 ~ /Trn-status: INCOMPLETE/ ) checkid[$2]=$2 ;
if ( $2 == checkid[$2] ) {
if ( $0 ~ /TECHNICAL EXCEPTION/ ) print checkid[$2]
}
}' logfile
解释:
-F'[\;\=]'
使用;
或=
作为字段分隔符;使用方括号允许您定义多个字段分隔符,分号和等号是特殊字符,因此awk
您需要使用反斜杠对其进行转义- 第一行:
$0
代表整行,~
是(子)模式匹配运算符和/PATTERN/
搜索字符串。因此,如果我们Trn-status: INCOMPLETE
在一行中找到,我们将 ID(由其他字段分隔的第二个字段)保存;
在=
一个数组中checkid
,其中索引是 ID 本身的名称(awk
允许使用字符串作为索引计数器) - 第二行:如果我们在另一行找到 ID ...
- 第三行:检查是否出现
TECHNICAL EXCEPTION
并打印 ID(如果出现) - (
logfile
是你的文件名)
答案2
此任务对于 来说太复杂grep
,但您可以使用sed
,例如:
sed '/Trn-status:/h;/\\"message\\":\\"TECHNICAL EXCEPTION\\"/!d;G;/Trn-status: INCOMPLETE/!d;s/.*"errorCode\\":\\"//;s/\\".*//' yourfile
/Trn-status:/h
始终保存保留Trn-status
空间中的最后一行/\\"message\\":\\"TECHNICAL EXCEPTION\\"/!d
表示删除没有 ( ) 给定模式的d
所有行。!
请注意,反斜杠需要用另一个反斜杠转义- 脚本的其余部分仅处理
TECHNICAL EXCEPTION
消息,但现在我们需要验证 isTrn-status
,INCOMPLETE
因此我们将保留空间附加到G
anddelete
如果我们没有找到Trn-status: INCOMPLETE
- 现在只需删除您要查找的代码之前 (
s/.*"errorCode\\":\\"//
) 和之后 ( )的部分即可。s/\\".*//
答案3
无耻地在 @Fiximan 的基础上构建了有关awk
.
假设数据中的内容不确定,因此遍历字段以查找实际的错误代码。
awk -F'[:;,=]' '{
if ( $0 ~ /Trn-status: INCOMPLETE/ ) checkid[$2]=$2 ;
if ( $2 == checkid[$2] && $0 ~ /TECHNICAL EXCEPTION/ ) {
for (i=1; i<=NF; i++) {if ( $i ~ "\"errorCode") print $(i+1), $2
}
}
}' logfile | sed "s/[\\\"]//g"