ImJustAFriend has asked for the wisdom of the Perl Monks concerning the following question:

Hello again monks. Now that I have the right log file to code against, I have come across another issue. I have a log formatted like this:
<13>Nov 15 21:26:00 OamCOMM[365626]: TIMESTAMP=Thu Nov 15 21:26:00 2018 MSGCLS=OAMOPE Title=OAM Create OPERATION Severity=Inform message={username:xxxxxxxx@xxxxxxxxxxxxxxxxxxx; causeDISTINGUISH_NAME=label=x,label=x,;label=x,label=xxxxxxxxxxxxxxx, +label=x,label=xxxx USER_LABEL= ******************* parameters after change =******************* label=xxxxxxxxxxxxx label=xxxxxxxxxxxxxxxxxxxxxxx label=xxxxxxxxxxxxxxxxxxxxxxxxxxxx label=sxxxxxxxxxxxxxxxxxxxxxxxxxxxxx label=xxxxxxxxxxxx ******************* xxxxxxxxxxxx =******************* label=x } Message Id=xxxxxxxx
For troubleshooting purposes I extracted one "chunk" of the log and put it into a text file t.txt. I then crafted t.pl to see if I could get the coding to work without impacting my larger script. Basically, I need to capture everything between "message=" and "Message Id" for this log entry. I am thinking in an array for processing after extraction. I have literally tried 40 different ideas, either my own or found on internet search, and nothing works. Here's my t.pl code I'm trying to make work:
#!/bin/perl use strict; use warnings; use Data::Dumper; my $mlsf = "t.txt"; my @res; open IN, "<", $mlsf or die "IN: $!\n"; while (my $mls = <IN>) { @res = $mls =~ m/^.*message=(.*?)Message Id.*$/gs; } print Dumper (\@res);
When I execute this script, I get:
$VAR1 = [];
Anyone have any ideas?

Replies are listed 'Best First'.
Re: Multiple Line Regex Not Working
by jwkrahn (Abbot) on Nov 15, 2018 at 22:34 UTC

    You are reading the file one line at a time so your regular expression will not work.

    This should work:

    while ( my $mls = <IN> ) { push @res, $mls if $mls =~ /^message=/ .. $mls =~ /^Message Id/; }
      That worked like a champ!! Thank you!!
Re: Multiple Line Regex Not Working
by kcott (Archbishop) on Nov 16, 2018 at 07:12 UTC

    G'day ImJustAFriend,

    Instead of reading one line at a time, you could read one chunk at a time by setting $/ (see perlvar: $/).

    Here's a quick-and-dirty example script to demonstrate the technique. I pared down your posted data substantially; duplicated it; then labelled with "CHUNK 1" and "CHUNK 2".

    #!/usr/bin/env perl use strict; use warnings; { local $/ = "\nMessage Id"; while (<DATA>) { chomp; /^message=(.*)\z/ms && print "$1\n"; } } __DATA__ <13>Nov 15 21:26:00 OamCOMM[365626]: TIMESTAMP=Thu Nov 15 21:26:00 2018 ... Severity=Inform message={username:xxxxxxx... causeDISTINGUISH_NAME=... ... CHUNK 1 ... label=x } Message Id=xxxxxxxx <13>Nov 15 21:26:00 OamCOMM[365626]: TIMESTAMP=Thu Nov 15 21:26:00 2018 ... Severity=Inform message={username:xxxxxxx... causeDISTINGUISH_NAME=... ... CHUNK 2 ... label=x } Message Id=xxxxxxxx

    Output:

    {username:xxxxxxx... causeDISTINGUISH_NAME=... ... CHUNK 1 ... label=x } {username:xxxxxxx... causeDISTINGUISH_NAME=... ... CHUNK 2 ... label=x }

    — Ken