Bash 如何在一个图案和以另一个图案开始的线条之间打印线条?
我需要你的帮助,用AWK(最好)解析日志文件,以便只提取必要的信息。我对其进行了大量简化,以使其更加可见,它看起来如下所示:Bash 如何在一个图案和以另一个图案开始的线条之间打印线条?,bash,awk,sed,grep,Bash,Awk,Sed,Grep,我需要你的帮助,用AWK(最好)解析日志文件,以便只提取必要的信息。我对其进行了大量简化,以使其更加可见,它看起来如下所示: 2019-05-22 HH:MM:SS name:Jhon 1 + random_text LOG_TEXT 1 LOG_TEXT 1 2019-05-22 HH:MM:SS whatever:Jhon 1 + random_text 2019-05-22 HH:MM:SS name:Jhon 2 + random_text LOG_TEXT 2 LOG_TEXT 2 2
2019-05-22 HH:MM:SS name:Jhon 1 + random_text
LOG_TEXT 1
LOG_TEXT 1
2019-05-22 HH:MM:SS whatever:Jhon 1 + random_text
2019-05-22 HH:MM:SS name:Jhon 2 + random_text
LOG_TEXT 2
LOG_TEXT 2
2019-05-22 HH:MM:SS ANYTHING 2 + random_text
2019-05-22 HH:MM:SS name:Jhon 3 + random_text
LOG_TEXT 3
LOG_TEXT 3
2019-05-22 HH:MM:SS name:Jhon 3 + random_text
2019-05-22 HH:MM:SS name:Jhon 1 + random_text
LOG_TEXT 1
LOG_TEXT 1
2019-05-22 HH:MM:SS name:Jhon 2 + random_text
LOG_TEXT 2
LOG_TEXT 2
2019-05-22 HH:MM:SS name:Jhon 3 + random_text
LOG_TEXT 3
LOG_TEXT 3
2019-05-22 HH:MM:SS name:Jhon 3 + random_text
详细说明:
总体思路是只过滤包含“name:Jhon”(不包含whater:Jhon)及其相应日志文本(可以包含任何内容,并且没有时间戳!)的行
我在每行末尾编号,以使3组可能的情况更加明显(日志文本以“which:JHON”(1行未打印)结尾;以通用的已盖销行“ANYTHING”(2行未打印);或以“name:JHON”(3行打印)结尾)
该功能是Vmware Vrealize orchestrator中工作流的一部分(因此实际语言是JS,但我可以使用ssh和awk),但我不会深入讨论 我尝试过各种awk和regex模式,但都没有找到答案。 我能得到的最接近的是类似的东西:
awk '/Jhon/{flag=1}/whatever/{flag=0}flag' file.txt
但是这是错误的,因为我认为“任何”都是固定的模式,而且,在这种情况下,包含“任何东西”的线都不被过滤。事实上,“whatever”和“anything”(以及随机文本和时间)可以是任何文学。因此,停止匹配的唯一方法是在以日期格式开头的行上停止匹配(但我不能使用2019,因为它被用于每个非LOG_文本行)
还尝试了一些JS正则表达式,但它太复杂了 最终输出应如下所示:
2019-05-22 HH:MM:SS name:Jhon 1 + random_text
LOG_TEXT 1
LOG_TEXT 1
2019-05-22 HH:MM:SS whatever:Jhon 1 + random_text
2019-05-22 HH:MM:SS name:Jhon 2 + random_text
LOG_TEXT 2
LOG_TEXT 2
2019-05-22 HH:MM:SS ANYTHING 2 + random_text
2019-05-22 HH:MM:SS name:Jhon 3 + random_text
LOG_TEXT 3
LOG_TEXT 3
2019-05-22 HH:MM:SS name:Jhon 3 + random_text
2019-05-22 HH:MM:SS name:Jhon 1 + random_text
LOG_TEXT 1
LOG_TEXT 1
2019-05-22 HH:MM:SS name:Jhon 2 + random_text
LOG_TEXT 2
LOG_TEXT 2
2019-05-22 HH:MM:SS name:Jhon 3 + random_text
LOG_TEXT 3
LOG_TEXT 3
2019-05-22 HH:MM:SS name:Jhon 3 + random_text
我想试试这样的东西:
awk '$1 ~ /[0-9]{4}-[0-9]{2}-[0-9]{2}/{if($0~/name:Jhon/){flag=1}else{flag=0}}flag' file.txt
说明:
- a~/pattern/将检查变量
是否匹配a
pattern
- 在代码中,您使用了
。此表达式只是/Jhon/{flag=1}
的快捷方式。如果行($0)与模式匹配,则将执行块$0~/Jhon/{flag=1}
{flag=1}
表示如果行的第一列与日期格式匹配,则将执行块$1~/[0-9]{4}-[0-9]{2}-[0-9]{2}/
但当然,如果日志文本以日期开头,它将失败 如果日志文本始终在两行上,您可以尝试以下操作:
awk '{counter-=1}/name:Jhon/{counter=3}counter>0' file.txt
返回
2019-05-22 HH:MM:SS name:Jhon 1 + random_text
LOG_TEXT 1
LOG_TEXT 1
2019-05-22 HH:MM:SS name:Jhon 2 + random_text
LOG_TEXT 2
LOG_TEXT 2
2019-05-22 HH:MM:SS name:Jhon 3 + random_text
LOG_TEXT 3
LOG_TEXT 3
2019-05-22 HH:MM:SS name:Jhon 3 + random_text
日志文本是任意行数的任意随机文本。我测试了你的awk,看起来不错。在我的例子中,LOG_文本不会以日期开头(因为它实际上是一个JSON)。如果我发现任何情况都不起作用,我会回来的。你介意解释一下小部分背后的逻辑吗?我不确定我是否理解您如何使用“~”。多谢各位!