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

Hi, there! I want to extract all the occurrence of the string starting with the message whose name is "MSG_ID_CELL_INFO_PRINT", and the string starting with the end message name "MSG_ID_CELL_CAMP_REQ". And I also want to compare the "cellid" value of the "MSG_ID_CELL_INFO_PRINT" which is closest to the "MSG_ID_CELL_CAMP_REQ", i.e., the line whose sn=11 vs the line whose sn=15 and sn=24 vs sn=25. If the "cellid" is different, then save all the "MSG_ID_CELL_INFO_PRINT" (or maybe five instances, not all) before the "MSG_ID_CELL_CAMP_REQ" including the "MSG_ID_CELL_CAMP_REQ" into another file. Here is the example data:

MSG_ID_CELL_INFO_PRINT sn=1 cellid=2; MSG_ID_CAMP_RSP sn=2 cellid=2; MSG_ID_CELL_INFO_PRINT sn=3 cellid=5; MSG_ID_CELL_INFO_PRINT sn=5 cellid=2; MSG_ID_CAMP_RSP sn=6 cellid=4; MSG_ID_CAMP_RSP sn=8 cellid=2; MSG_ID_CELL_INFO_PRINT sn=10 cellid=2; MSG_ID_CELL_INFO_PRINT sn=11 cellid=5; MSG_ID_CAMP_RSP sn=12 cellid=2; MSG_ID_CAMP_RSP sn=14 cellid=3; MSG_ID_CELL_CAMP_REQ sn=15 cellid=2; MSG_ID_CELL_INFO_PRINT sn=16 cellid=2; MSG_ID_CELL_INFO_PRINT sn=17 cellid=2; MSG_ID_CELL_INFO_PRINT sn=18 cellid=2; MSG_ID_CAMP_RSP sn=19 cellid=2; MSG_ID_CELL_INFO_PRINT sn=20 cellid=5; MSG_ID_CELL_INFO_PRINT sn=21 cellid=2; MSG_ID_CAMP_RSP sn=22 cellid=4; MSG_ID_CAMP_RSP sn=23 cellid=2; MSG_ID_CELL_INFO_PRINT sn=24 cellid=2; MSG_ID_CELL_CAMP_REQ sn=25 cellid=2;

The expected results are: since the "cellid" of "MSG_ID_CELL_INFO_PRINT sn=11 cellid=5;" and "MSG_ID_CELL_CAMP_REQ sn=15 cellid=2;" is different, this information block what I want;

MSG_ID_CELL_INFO_PRINT sn=1 cellid=2; MSG_ID_CAMP_RSP sn=2 cellid=2; MSG_ID_CELL_INFO_PRINT sn=3 cellid=5; MSG_ID_CELL_INFO_PRINT sn=5 cellid=2; MSG_ID_CAMP_RSP sn=6 cellid=4; MSG_ID_CAMP_RSP sn=8 cellid=2; MSG_ID_CELL_INFO_PRINT sn=10 cellid=2; MSG_ID_CELL_INFO_PRINT sn=11 cellid=5; MSG_ID_CAMP_RSP sn=12 cellid=2; MSG_ID_CAMP_RSP sn=14 cellid=3; MSG_ID_CELL_CAMP_REQ sn=15 cellid=2;

And the "cellid" of "MSG_ID_CELL_INFO_PRINT sn=24 cellid=2;"and "MSG_ID_CELL_CAMP_REQ sn=25 cellid=2;" is same, so this information block is not what I want

MSG_ID_CELL_INFO_PRINT sn=16 cellid=2; MSG_ID_CELL_INFO_PRINT sn=17 cellid=2; MSG_ID_CELL_INFO_PRINT sn=18 cellid=2; MSG_ID_CAMP_RSP sn=19 cellid=2; MSG_ID_CELL_INFO_PRINT sn=20 cellid=5; MSG_ID_CELL_INFO_PRINT sn=21 cellid=2; MSG_ID_CAMP_RSP sn=22 cellid=4; MSG_ID_CAMP_RSP sn=23 cellid=2; MSG_ID_CELL_INFO_PRINT sn=24 cellid=2; MSG_ID_CELL_CAMP_REQ sn=25 cellid=2;

This is my code, I can not figure out how to solve the "nearest compare".

my $str = shift; #the data showed in the above my $beg = "MSG_ID_CELL_INFO_PRINT"; my $end = "MSG_ID_CELL_CAMP_REQ"; my $key1 = "cellid="; my $key2 = ";"; while ($str =~ m/$beg.*?$key1(\d+)(.*?)$end(.*?)$key1(\d+)/g) { my $info_cell = $2; my $camp_cell = $4; if ($info_cell ne $camp_cell) { my $cell_info = $beg.$1.$key1.$2.$end; while ($cell_info =~ m/$beg(.*?)$key2/g) { my $print_info = $1; print FILEOUT "$beg.$print_info"; } } }

The problems of the code are that: first, it compare the first occurrence of the "MSG_ID_CELL_INFO_PRINT" with the "MSG_ID_CELL_CAMP_REQ", for example, sn=1 vs sn=15, which should be sn=11 vs sn=15; Second, once the number of compared value increase, it will be troubled. Also, I can not put the content of the message "MSG_ID_CELL_CAMP_REQ" into file. Any suggestions will be helpful, Thanks!

  • Comment on Extract all occurrence of one msg and compare the value of the msg which is closest to the end msg
  • Select or Download Code

Replies are listed 'Best First'.
Re: Extract all occurrence of one msg and compare the value of the msg which is closest to the end msg
by kcott (Archbishop) on May 30, 2013 at 06:12 UTC

    G'day dwslovedh,

    I found your problem description very hard to follow. Do you want something like this?

    #!/usr/bin/env perl use strict; use warnings; my $closest; while (<DATA>) { print; if (/^MSG_ID_CELL_INFO_PRINT/) { $closest = $_; } if (/^MSG_ID_CELL_CAMP_REQ/) { print "\tClosest: $closest"; } } __DATA__ MSG_ID_CELL_INFO_PRINT sn=1 cellid=2; MSG_ID_CAMP_RSP sn=2 cellid=2; MSG_ID_CELL_INFO_PRINT sn=3 cellid=5; MSG_ID_CELL_INFO_PRINT sn=5 cellid=2; MSG_ID_CAMP_RSP sn=6 cellid=4; MSG_ID_CAMP_RSP sn=8 cellid=2; MSG_ID_CELL_INFO_PRINT sn=10 cellid=2; MSG_ID_CELL_INFO_PRINT sn=11 cellid=5; MSG_ID_CAMP_RSP sn=12 cellid=2; MSG_ID_CAMP_RSP sn=14 cellid=3; MSG_ID_CELL_CAMP_REQ sn=15 cellid=2; MSG_ID_CELL_INFO_PRINT sn=16 cellid=2; MSG_ID_CELL_INFO_PRINT sn=17 cellid=2; MSG_ID_CELL_INFO_PRINT sn=18 cellid=2; MSG_ID_CAMP_RSP sn=19 cellid=2; MSG_ID_CELL_INFO_PRINT sn=20 cellid=5; MSG_ID_CELL_INFO_PRINT sn=21 cellid=2; MSG_ID_CAMP_RSP sn=22 cellid=4; MSG_ID_CAMP_RSP sn=23 cellid=2; MSG_ID_CELL_INFO_PRINT sn=24 cellid=2; MSG_ID_CELL_CAMP_REQ sn=25 cellid=2;

    Output:

    $ pm_msg_block_extract.pl MSG_ID_CELL_INFO_PRINT sn=1 cellid=2; MSG_ID_CAMP_RSP sn=2 cellid=2; MSG_ID_CELL_INFO_PRINT sn=3 cellid=5; MSG_ID_CELL_INFO_PRINT sn=5 cellid=2; MSG_ID_CAMP_RSP sn=6 cellid=4; MSG_ID_CAMP_RSP sn=8 cellid=2; MSG_ID_CELL_INFO_PRINT sn=10 cellid=2; MSG_ID_CELL_INFO_PRINT sn=11 cellid=5; MSG_ID_CAMP_RSP sn=12 cellid=2; MSG_ID_CAMP_RSP sn=14 cellid=3; MSG_ID_CELL_CAMP_REQ sn=15 cellid=2; Closest: MSG_ID_CELL_INFO_PRINT sn=11 cellid=5; MSG_ID_CELL_INFO_PRINT sn=16 cellid=2; MSG_ID_CELL_INFO_PRINT sn=17 cellid=2; MSG_ID_CELL_INFO_PRINT sn=18 cellid=2; MSG_ID_CAMP_RSP sn=19 cellid=2; MSG_ID_CELL_INFO_PRINT sn=20 cellid=5; MSG_ID_CELL_INFO_PRINT sn=21 cellid=2; MSG_ID_CAMP_RSP sn=22 cellid=4; MSG_ID_CAMP_RSP sn=23 cellid=2; MSG_ID_CELL_INFO_PRINT sn=24 cellid=2; MSG_ID_CELL_CAMP_REQ sn=25 cellid=2; Closest: MSG_ID_CELL_INFO_PRINT sn=24 cellid=2;

    -- Ken

Re: Extract all occurrence of one msg and compare the value of the msg which is closest to the end msg
by Laurent_R (Canon) on May 29, 2013 at 20:57 UTC

    Sorry, I don't understand what you want to do. Can you restate it in simpler/more descriptive terms?