Reputation: 39
I have a log file like 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
I want to use a perl one-liner to find the most recent timestamp before "THIS IS MATCHED STRING".
I tried this:
perl -0777 -nle 'print "$1\n" while m/(\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d).+?THIS IS MATCHED STRING/sg'
But it matched the first timestamp, "2018-07-10 10:03:01" instead of the "2018-07-10 10:03:03" that I wanted. Obviously (at least I think), I don't have a good understanding of how the greedy/lazy matching is working.
Any help would be appreciated!
Upvotes: 1
Views: 187
Reputation: 66883
For a fairly elementary approach, which avoids an involved regex, process line by line and when a timestamp pattern is matched record it. Then as you run into pattern THIS...
you will have had the (last) previous timestamp.
perl -wnE'
$ts = $1 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
If the timestamp is captured and saved with ($ts) = /.../
then failed matches on lines without it turn it undef
, so it may not be there when THIS
is found. Thus it is saved from $1
only once there is a match.
The defined-or (//
) on $ts
is used in case the file had no time stamps at all before THIS
Upvotes: 3
Reputation: 43169
You could use
^
(\d{4}-\d{2}-\d{2}\ \d+:\d+:\d+):
(?:(?!^\d{4})[\s\S])+?
\QTHIS IS MATCHED STRING\E
Upvotes: 0