当搜索字符串存在时,我正在从给定日期范围内的文件中搜索多个行范围。我不是 Unix 专家,不知道如何实现这一点。谷歌搜索后,我能够使用 awk 和 sed 命令(如下所述)显示日期范围内的日志,但无法添加搜索条件。以下是日志文件格式:
日志文件内容
[2020/07/05 21:10:28.961][INFO ][ABCDDDDDDD]
------------------------------------------------------------
ID: ABCDDGSDFEWRER
MESSAGE: Event Message received.
------------------------------------------------------------
CONTEXT: {
"ID" : 1,
"BC" : 9789,
"event" : "something",
COMMON_TEXT: COMMON
"valid" : true
}
************************************************************
[2020/07/05 21:10:28.816][INFO ][ABCDDDDDEEEEEEE]
------------------------------------------------------------
ID: ABCDDSDFSDFSDFSDFSDFSDFSDFFEWRER
MESSAGE: Event Message received.
------------------------------------------------------------
CONTEXT: {
"ID" : 1,
"BC" : 9089,
"event" : "One More thing",
COMMON_TEXT: COMMON
"valid" : true
}
************************************************************
[2020/07/05 21:10:43.816][INFO ][ABCDDDDDEEFFFFFFFFFFFFFEEE]
------------------------------------------------------------
ID: QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
MESSAGE: Event Message received.
------------------------------------------------------------
CONTEXT: {
"ID" : 1,
"BC" : 9789,
"event" : "Second thing",
COMMON_TEXT: COMMON
"valid" : False
}
************************************************************
我当前使用的命令:
awk
:(获取准确的开始时间,因为 sed 命令无法识别准确的开始时间)awk 'substr($1,2,11)>="2020\/07\/05" && substr($1,2,11)<="2020\/07\/05" && substr($2,1,8)>="21:10:28" && substr($2,1,8)<="21:10:43" {print $0}' logfileName
sed
:获取给定时间范围内的日志(两个日期之间的块)。不需要打印中间块(因为它不包含 9789,尽管在我的时间范围内)sed -n '/2020\/07\/05 21:10:28.010/,/2020\/07\/05 21:10:30.668/{;p};/2020\/07\/05 21:10:30.668/,/\*\*\*/{;p}' logfileName
这是我正在寻找的示例输出: 1. 下面的两个块在我想要的时间限制内 2. 它包含“BC”:9789(我想要的数字) 目前我正在使用上述两个命令组合和处理验证(9789) 通过使用 java 代码删除中间块。
[2020/07/05 21:10:28.961][INFO ][ABCDDDDDDD]
------------------------------------------------------------
ID: ABCDDGSDFEWRER
MESSAGE: Event Message received.
------------------------------------------------------------
CONTEXT: {
"ID" : 1,
"BC" : 9789,
"event" : "something",
COMMON_TEXT: COMMON
"valid" : true
}
************************************************************
[2020/07/05 21:10:43.816][INFO ][ABCDDDDDEEFFFFFFFFFFFFFEEE]
------------------------------------------------------------
ID: QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
MESSAGE: Event Message received.
------------------------------------------------------------
CONTEXT: {
"ID" : 1,
"BC" : 9789,
"event" : "Second thing",
COMMON_TEXT: COMMON
"valid" : False
}
************************************************************
答案1
这有点冗长,因为:
..它适当地公开变量,使它们成为脚本的参数,假设这不是一次性的。
..它具有可读性和适应性。
..它显示了日志条目的整个块,从时间戳到包含所有星号的下一行。
#! /bin/bash
Low='2020/07/05 21:10:28'
End='2020/07/05 21:10:43'
AWK='
BEGIN {
reTS = "[[]20../../.. ..:..:..[.]...[]]";
reStop = "^[*]+$";
}
function Range (ts) {
return ((ts < Low || ts > End) ? "N" : "Y");
}
match ($0, reTS) { Block = Range( substr ($0, RSTART+1, RLENGTH-6)); }
Block == "Y" { print; }
$0 ~ reStop { Block = "N"; }
'
awk -v Low="${Low}" -v End="${End}" "${AWK}" myLog.txt
答案2
只需对 sed 命令进行轻微更改
sed -n '/2020\/07\/05 21:10:28\.010/,/2020\/07\/05 21:10:30\.668/{;p};/2020\/07\/05 21:10:30\.668/,/\*\*\*/{;p}'
你的命令只需要转义。通过在其前面放置反斜杠。即2020/07/05 21:10:28\.010