regex help

regex help

am 10.10.2011 21:56:27 von Chris Stinemetz

Any help is appreciated.

Once I match HEH how can alter the program to print the contents that
are in the two lines directly above the match?

For example in this case I would like the print results to be:

**01 REPT:CELL 983 CDM 1, CCU 1, CE 5, HEH Timestamp: 10/10/11 00:01:18

#!/usr/bin/perl

use warnings;
use strict;

while(my $hehline = ) {
chomp $hehline;
if ($hehline =~ /, HEH/) {
print "$hehline \n";
}
}



__DATA__
10/10/11 00:01:17 #984611

A 01 REPT:CELL 833 CP FAILURE, UNANSWERED TERMINATION
CDMA TRAFFIC CHANNEL CONFIRMATION FAILURE
TRAFFIC CHANNEL FAILURE REASON - ACQUIRE MOBILE FAILURE [2]
DCS 1 TG 1723 TM 374 SG 0 ANT 2
CARRIER 4, CHAN UNAVAIL FS-ECP ID 1, SYS ID 4681
DN 3168710330, MIN 3164094259, IMSI UNAVAIL
SN ###2ddff3 MEID Xa00000###629cc SCM ba
ALW CDMA, ASGN CDMA
CDM 1, CCU 2, CE 64, MLG 1/MLG_CDM 1
DCS 1/PSU 0/SM 3/BHS 6, ECP ID 1, SYS ID 4681



10/10/11 00:01:18 #984614

**01 REPT:CELL 983 CDM 1, CCU 1, CE 5, HEH
SUPPRESSED MSGS: 0
FT PL SECTOR 3 CARRIER 1 (1.9 GHz PCS)
FAILURE: OUT OF RANGE
PILOT LEVEL: MEASURED = 28.3 dBm EXPECTED = 33.8 dBm
SECONDARY UNIT: CDM 1, CBR 3

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: regex help

am 10.10.2011 22:16:27 von Brian Fraser

--0015174a0fae454b1904aef777f8
Content-Type: text/plain; charset=UTF-8

On Mon, Oct 10, 2011 at 4:56 PM, Chris Stinemetz
wrote:

> Any help is appreciated.
>
> Once I match HEH how can alter the program to print the contents that
> are in the two lines directly above the match?
>
> For example in this case I would like the print results to be:
>
> **01 REPT:CELL 983 CDM 1, CCU 1, CE 5, HEH Timestamp: 10/10/11 00:01:18
>
> #!/usr/bin/perl
>
> use warnings;
> use strict;
>
> while(my $hehline = ) {
> chomp $hehline;
> if ($hehline =~ /, HEH/) {
> print "$hehline \n";
> }
> }
>
>
>
> __DATA__
> 10/10/11 00:01:17 #984611
>
> A 01 REPT:CELL 833 CP FAILURE, UNANSWERED TERMINATION
> CDMA TRAFFIC CHANNEL CONFIRMATION FAILURE
> TRAFFIC CHANNEL FAILURE REASON - ACQUIRE MOBILE FAILURE [2]
> DCS 1 TG 1723 TM 374 SG 0 ANT 2
> CARRIER 4, CHAN UNAVAIL FS-ECP ID 1, SYS ID 4681
> DN 3168710330, MIN 3164094259, IMSI UNAVAIL
> SN ###2ddff3 MEID Xa00000###629cc SCM ba
> ALW CDMA, ASGN CDMA
> CDM 1, CCU 2, CE 64, MLG 1/MLG_CDM 1
> DCS 1/PSU 0/SM 3/BHS 6, ECP ID 1, SYS ID 4681
>
>
>
> 10/10/11 00:01:18 #984614
>
> **01 REPT:CELL 983 CDM 1, CCU 1, CE 5, HEH
> SUPPRESSED MSGS: 0
> FT PL SECTOR 3 CARRIER 1 (1.9 GHz PCS)
> FAILURE: OUT OF RANGE
> PILOT LEVEL: MEASURED = 28.3 dBm EXPECTED = 33.8 dBm
> SECONDARY UNIT: CDM 1, CBR 3
>
> --
> To unsubscribe, e-mail: beginners-unsubscribe@perl.org
> For additional commands, e-mail: beginners-help@perl.org
> http://learn.perl.org/
>
>
> Couple of ways.
You could save the line numbers on the first pass, then read the file again
and print the relevant lines; Remember that $. has the current line number.
my @lines;
while (...) {
...
if (/,\s+HEH/) {
push @lines, $.;
}
}

Or you could do the same as above, but use Tie::File instead of reading the
file twice.

Or you could keep saving the previous two lines (this assumes the HEH can't
be on the first two lines. If it can, you'll have to modify the proggy
accordingly):
my ($one, $two) = (scalar , scalar );
while (my $hehline = ) {
...
if (/,\s+HEH/) {
say "[$one]\n[$two]";
}
($one, $two) = ($two, $hehline);
}

Or, looking at your data, you could read "paragraphs" instead of
line-by-line -- Apparently each chunk is separated by three (four?)
newlines, so

{
local $/ = "\n\n\n";
while (my $hehline = ) {
... # shenanigans here
}
}

--0015174a0fae454b1904aef777f8--

Re: regex help

am 10.10.2011 22:59:50 von Chris Charley

>"Chris Stinemetz" wrote in message
>
>Any help is appreciated.
>
>Once I match HEH how can alter the program to print the contents that
>are in the two lines directly above the match?
>
>For example in this case I would like the print results to be:
>
>**01 REPT:CELL 983 CDM 1, CCU 1, CE 5, HEH Timestamp: 10/10/11 00:01:18


[snip code and data]

I think the following should work.

Chris

#!/usr/bin/perl
use strict;
use warnings;

my $dt; # date_time
while () {
chomp;
if (m!^(\d\d/\d\d/\d\d \d\d:\d\d:\d\d)!) {
$dt = $1;
}
elsif (/HEH$/) {
print "$_ Timestamp $dt\n";
}
}

__DATA__
10/10/11 00:01:17 #984611

A 01 REPT:CELL 833 CP FAILURE, UNANSWERED TERMINATION
CDMA TRAFFIC CHANNEL CONFIRMATION FAILURE
TRAFFIC CHANNEL FAILURE REASON - ACQUIRE MOBILE FAILURE [2]
DCS 1 TG 1723 TM 374 SG 0 ANT 2
CARRIER 4, CHAN UNAVAIL FS-ECP ID 1, SYS ID 4681
DN 3168710330, MIN 3164094259, IMSI UNAVAIL
SN ###2ddff3 MEID Xa00000###629cc SCM ba
ALW CDMA, ASGN CDMA
CDM 1, CCU 2, CE 64, MLG 1/MLG_CDM 1
DCS 1/PSU 0/SM 3/BHS 6, ECP ID 1, SYS ID 4681



10/10/11 00:01:18 #984614

**01 REPT:CELL 983 CDM 1, CCU 1, CE 5, HEH
SUPPRESSED MSGS: 0
FT PL SECTOR 3 CARRIER 1 (1.9 GHz PCS)
FAILURE: OUT OF RANGE
PILOT LEVEL: MEASURED = 28.3 dBm EXPECTED = 33.8 dBm
SECONDARY UNIT: CDM 1, CBR 3

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: regex help

am 10.10.2011 23:18:22 von jwkrahn

Chris Stinemetz wrote:
> Any help is appreciated.

It looks like you don't need "regex help".

> Once I match HEH how can alter the program to print the contents that
> are in the two lines directly above the match?
>
> For example in this case I would like the print results to be:
>
> **01 REPT:CELL 983 CDM 1, CCU 1, CE 5, HEH Timestamp: 10/10/11 00:01:18
>
> #!/usr/bin/perl
>
> use warnings;
> use strict;
>
> while(my $hehline =) {
> chomp $hehline;
> if ($hehline =~ /, HEH/) {
> print "$hehline \n";
> }
> }

You could simplify that by not removing the newline and then adding it
back in:

while ( my $hehline = ) {
if ( $hehline =~ /, HEH/ ) {
print $hehline;
}
}

And even simpler by not using the $hehline variable:

while ( ) {
print if /, HEH/;
}

But, back to your real problem.

I can think of two ways to do it.

Number one: if you are sure that the line you want is _always_ two lines
above you could use an array to hold the line you need:

my @buffer;
while ( my $hehline = ) {
push @buffer, $hehline;
shift @buffer if @buffer > 3;
if ( $hehline =~ /, HEH/ ) {
print $buffer[ 0 ];
}
}


Number two: better to just capture the line you require and only print
it when the regular expression matches:

my $capture;
while ( my $hehline = ) {
$capture = $hehline if $hehline =~
m{^\d+/\d+/\d+\s+\d+:\d+:\d+\s+#\d+$};
if ( $hehline =~ /, HEH/ ) {
print $capture;
}
}



John
--
Any intelligent fool can make things bigger and
more complex... It takes a touch of genius -
and a lot of courage to move in the opposite
direction. -- Albert Einstein

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: regex help

am 11.10.2011 00:01:12 von Shawn H Corey

On 11-10-10 03:56 PM, Chris Stinemetz wrote:
> Any help is appreciated.
>
> Once I match HEH how can alter the program to print the contents that
> are in the two lines directly above the match?
>
> For example in this case I would like the print results to be:
>
> **01 REPT:CELL 983 CDM 1, CCU 1, CE 5, HEH Timestamp: 10/10/11 00:01:18

This is not quite what you asked for but it shows how to print lines
before a match:

#!/usr/bin/env perl

use strict;
use warnings;

# number of lines to save
my $save_nbr = 2;

# save lines before pattern match
# use undef for lines before beginning
my @lines = ( undef ) x $save_nbr;

while(my $hehline = ) {
chomp $hehline;

if ($hehline =~ /, HEH/) {

# print before lines
print "$_\n" for ( grep { defined } @lines );

# print current line
print "$hehline\n";
}

# remove first saved line
shift @lines;

# save current line
push @lines, $hehline;
}



__DATA__
10/10/11 00:01:17 #984611

A 01 REPT:CELL 833 CP FAILURE, UNANSWERED TERMINATION
CDMA TRAFFIC CHANNEL CONFIRMATION FAILURE
TRAFFIC CHANNEL FAILURE REASON - ACQUIRE MOBILE FAILURE [2]
DCS 1 TG 1723 TM 374 SG 0 ANT 2
CARRIER 4, CHAN UNAVAIL FS-ECP ID 1, SYS ID 4681
DN 3168710330, MIN 3164094259, IMSI UNAVAIL
SN ###2ddff3 MEID Xa00000###629cc SCM ba
ALW CDMA, ASGN CDMA
CDM 1, CCU 2, CE 64, MLG 1/MLG_CDM 1
DCS 1/PSU 0/SM 3/BHS 6, ECP ID 1, SYS ID 4681



10/10/11 00:01:18 #984614

**01 REPT:CELL 983 CDM 1, CCU 1, CE 5, HEH
SUPPRESSED MSGS: 0
FT PL SECTOR 3 CARRIER 1 (1.9 GHz PCS)
FAILURE: OUT OF RANGE
PILOT LEVEL: MEASURED = 28.3 dBm EXPECTED = 33.8 dBm
SECONDARY UNIT: CDM 1, CBR 3



--
Just my 0.00000002 million dollars worth,
Shawn

Confusion is the first step of understanding.

Programming is as much about organization and communication
as it is about coding.

The secret to great software: Fail early & often.

Eliminate software piracy: use only FLOSS.

"Make something worthwhile." -- Dear Hunter

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: regex help

am 11.10.2011 00:30:45 von John Delacour

At 14:56 -0500 10/10/11, Chris Stinemetz wrote:

>Once I match HEH how can alter the program to print the contents that
>are in the two lines directly above the match?

If it's only one instance you need to deal with then this should do the trick:


#!/usr/bin/perl
use strict;
my @lines;
while (){
chomp;
s/#.*$//;
push @lines, $_;
last if /HEH/;
}
print "$lines[-1] Timestamp: $lines[-3]";
__END__

JD

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/