在由某些字符分隔的日志文件中提取具有匹配模式的行
Extract lines with a matching pattern in log file delimited by some characters
我有一个这种格式的日志文件。
MATNR -- 0000000000090933887
Some text
in
between
*****Return Message** Successfully processed
some
more
text
blah
blah
-----------------------------------------
MATNR-000000000000090934206
some
text
in
between
*****Return Message** Successfully processed
some more text
blah
blah
between
--------------------------------------------
这就是我的日志文件的结构。我打算获取 MATNR 行和行 **** Return Message*** 上的消息。在日志中,每个新条目都由 ------------ 分隔。有没有办法使用 grep、sed、tcl 程序来有效地为我们执行此操作。
我尝试通过使用 z 选项的 grep 来尝试此操作。但我仍然不确定如何尝试在 those.Below 中获取匹配行,只是给出了被一些行包围的 MATNR。
grep -zPo '(\n-+\n)\K(.|\n)+?MATNR(.|\n)+?(?=\n-+\n)'
预期输出为
MATNR -- 0000000000090933887
*****Return Message** Successfully processed
MATNR-000000000000090934206
*****Return Message** Successfully processed
在 Tcl 中,当只打印匹配的行时,您会这样做(假设您将输入通过管道传输到标准输入并将其写入标准输出):
while {[gets stdin line] >= 0} {
if {[string match "MATNR*" $line] || [string match -nocase "*Return Message*" $line]} {
puts $line
}
}
同时打印这些标记之间的线条(grep
不擅长的任务):
set printing false
while {[gets stdin line] >= 0} {
if {[string match "MATNR*" $line]} {
# Start of interesting sequence
puts $line
set printing true
} elseif {[string match -nocase "*Return Message*" $line]} {
# End of interesting sequence
puts $line
set printing false
} elseif {$printing} {
# Middle of interesting sequence
puts $line
}
}
这不是最短的写法,但我认为它很清楚。
这可能适合您 (GNU sed):
sed -nE '/^MATNR/{:a;N;/^-+$/M!ba;s/\n.*\n([*]{5}Return Message[^\n]*).*/ /Ip}' file
关闭隐式打印 -n
并使正则表达式更加直观 -E
。
收集以 MATNR
开头并以仅包含 -
的行结尾的行。
*****Return Message
的模式匹配,如果找到则打印所需的格式。
编辑:
由于 OP 已经修改了问题,这可能就足够了:
sed -n '/MATNR/h;/Return Message/{H;g;p}' file
这个 awk
应该可以完成工作:
awk '/^MATNR/ {m=[=10=]} /Return Message/ {print m, [=10=]}' file
MATNR -- 0000000000090933887 *****Return Message** Successfully processed
MATNR-000000000000090934206 *****Return Message** Successfully processed
我有一个这种格式的日志文件。
MATNR -- 0000000000090933887
Some text
in
between
*****Return Message** Successfully processed
some
more
text
blah
blah
-----------------------------------------
MATNR-000000000000090934206
some
text
in
between
*****Return Message** Successfully processed
some more text
blah
blah
between
--------------------------------------------
这就是我的日志文件的结构。我打算获取 MATNR 行和行 **** Return Message*** 上的消息。在日志中,每个新条目都由 ------------ 分隔。有没有办法使用 grep、sed、tcl 程序来有效地为我们执行此操作。
我尝试通过使用 z 选项的 grep 来尝试此操作。但我仍然不确定如何尝试在 those.Below 中获取匹配行,只是给出了被一些行包围的 MATNR。
grep -zPo '(\n-+\n)\K(.|\n)+?MATNR(.|\n)+?(?=\n-+\n)'
预期输出为
MATNR -- 0000000000090933887
*****Return Message** Successfully processed
MATNR-000000000000090934206
*****Return Message** Successfully processed
在 Tcl 中,当只打印匹配的行时,您会这样做(假设您将输入通过管道传输到标准输入并将其写入标准输出):
while {[gets stdin line] >= 0} {
if {[string match "MATNR*" $line] || [string match -nocase "*Return Message*" $line]} {
puts $line
}
}
同时打印这些标记之间的线条(grep
不擅长的任务):
set printing false
while {[gets stdin line] >= 0} {
if {[string match "MATNR*" $line]} {
# Start of interesting sequence
puts $line
set printing true
} elseif {[string match -nocase "*Return Message*" $line]} {
# End of interesting sequence
puts $line
set printing false
} elseif {$printing} {
# Middle of interesting sequence
puts $line
}
}
这不是最短的写法,但我认为它很清楚。
这可能适合您 (GNU sed):
sed -nE '/^MATNR/{:a;N;/^-+$/M!ba;s/\n.*\n([*]{5}Return Message[^\n]*).*/ /Ip}' file
关闭隐式打印 -n
并使正则表达式更加直观 -E
。
收集以 MATNR
开头并以仅包含 -
的行结尾的行。
*****Return Message
的模式匹配,如果找到则打印所需的格式。
编辑:
由于 OP 已经修改了问题,这可能就足够了:
sed -n '/MATNR/h;/Return Message/{H;g;p}' file
这个 awk
应该可以完成工作:
awk '/^MATNR/ {m=[=10=]} /Return Message/ {print m, [=10=]}' file
MATNR -- 0000000000090933887 *****Return Message** Successfully processed
MATNR-000000000000090934206 *****Return Message** Successfully processed