perl 多行问题:需要一个衬里来打印文件中字符串之前的最后一个匹配项
perl multiline issue: need one liner to print last match before string in file
我有一个这样的日志文件:
2018-07-10 10:03:01: random text1
2018-07-10 10:03:02: random text2
2018-07-10 10:03:03: random text3
more text
and more
THIS IS MATCHED STRING
2018-07-10 10:03:04: random text4
我想使用 perl 单行查找 "THIS IS MATCHED STRING" 之前的最新时间戳。
我试过这个:
perl -0777 -nle 'print "\n" while m/(\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d).+?THIS IS MATCHED STRING/sg'
但它匹配了第一个时间戳,“2018-07-10 10:03:01”,而不是我想要的“2018-07-10 10:03:03”。显然(至少我认为),我不太了解 greedy/lazy 匹配的工作原理。
如有任何帮助,我们将不胜感激!
你可以使用
^
(\d{4}-\d{2}-\d{2}\ \d+:\d+:\d+):
(?:(?!^\d{4})[\s\S])+?
\QTHIS IS MATCHED STRING\E
对于一个相当基本的方法,它避免了涉及的正则表达式,逐行处理,并在时间戳模式匹配时记录它。然后,当您 运行 进入模式 THIS...
时,您将拥有(最后的)前一个时间戳。
perl -wnE'
$ts = if /(\d{4}-\d{2}-\d{2}[ ]\d{2}:\d{2}:\d{2})/;
say $ts // "no previous time stamp" if /THIS IS MATCHED STRING/;
' file.txt
如果时间戳被捕获并用 ($ts) = /.../
保存,那么在没有它的情况下在行上匹配失败 undef
,所以当找到 THIS
时它可能不存在。因此只有在匹配时才会从 </code> 中保存。</p>
<p><code>$ts
上的定义或 (//
) 用于防止文件在 THIS
之前根本没有时间戳
我有一个这样的日志文件:
2018-07-10 10:03:01: random text1
2018-07-10 10:03:02: random text2
2018-07-10 10:03:03: random text3
more text
and more
THIS IS MATCHED STRING
2018-07-10 10:03:04: random text4
我想使用 perl 单行查找 "THIS IS MATCHED STRING" 之前的最新时间戳。
我试过这个:
perl -0777 -nle 'print "\n" while m/(\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d).+?THIS IS MATCHED STRING/sg'
但它匹配了第一个时间戳,“2018-07-10 10:03:01”,而不是我想要的“2018-07-10 10:03:03”。显然(至少我认为),我不太了解 greedy/lazy 匹配的工作原理。
如有任何帮助,我们将不胜感激!
你可以使用
^
(\d{4}-\d{2}-\d{2}\ \d+:\d+:\d+):
(?:(?!^\d{4})[\s\S])+?
\QTHIS IS MATCHED STRING\E
对于一个相当基本的方法,它避免了涉及的正则表达式,逐行处理,并在时间戳模式匹配时记录它。然后,当您 运行 进入模式 THIS...
时,您将拥有(最后的)前一个时间戳。
perl -wnE'
$ts = if /(\d{4}-\d{2}-\d{2}[ ]\d{2}:\d{2}:\d{2})/;
say $ts // "no previous time stamp" if /THIS IS MATCHED STRING/;
' file.txt
如果时间戳被捕获并用 ($ts) = /.../
保存,那么在没有它的情况下在行上匹配失败 undef
,所以当找到 THIS
时它可能不存在。因此只有在匹配时才会从 </code> 中保存。</p>
<p><code>$ts
上的定义或 (//
) 用于防止文件在 THIS