Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Regular Expression matching a text string

Status
Not open for further replies.

Mpking

Technical User
Mar 2, 2002
23
US
Good afternoon,

I have a text file that is created on the fly, and it is scanned for a certain pattern as it is created.

One of our co-workers, who has since left, wrote a small script to do this.

If it sees a line that begins with a A, then it looks for a pattern that has DN7xxx where xxx is supposed to be any digit.
Then it compares the 7 digit number at the end of the line to a CSV file. If the number is in the CSV, it shoots an email off to a distribution list, and ftp a file off to somewhere else.

We need to modify this so that it it also looks for numbers that begin with 15xx and 16xx. (where xx can be any digit)

A friend who is good with Perl told me to replace the line:
Code:
if ( /^A .*(DN7... ) .*(\d{7,7})/ ){
with
Code:
if (/^A .*(DN((7\d)|(15)|(16))\d{2}) .*(\d{7,7})/) {

and
Code:
if( $DN =~ /DN7... / ){
with
Code:
if( $DN =~ DN((7\d)|(15)|(16))\d{2}){

This second statement is Line 31

However, this will generate an error:
Code:
Backslash found where operator expected at sdimon.tmp line 31, near "7\"
        (Missing operator before \?)
syntax error at sdimon.tmp line 31, near "7\"
Unquoted string "d" may clash with future reserved word at sdimon.tmp line 31.
Backslash found where operator expected at sdimon.tmp line 31, near ")\"
        (Missing operator before \?)
sdimon.tmp had compilation errors.

I found that if I added a / to the second statement so that it was thus:
Code:
if( $DN =~ /DN((7\d)|(15)|(16))\d{2}/){
It would compile, but it wouldn't work.

Would someone mind telling me what I'm doing wrong?

I'm attaching the complete modified script, minus the slash's:

Code:
#!/usr/bin/perl -w
#

$DEV="ttyS0";
$LOGFILE="cdr.log";
$LOGDIR="/var/log";     #change as needed.
$DBFILE="/root/USER.DB";

$SIG{INT}='rr_db';

&rr_db;


if ( ! -e "/dev/$DEV" ){
        print "Device: /dev/$DEV not found.\n";
        exit;
}

open(SERIAL, &quot;</dev/$DEV&quot;) || die &quot;$!\n&quot;;

select(SERIAL); $| = 1; select(STDOUT);

while(<SERIAL>){
        print &quot;$_&quot;;
        open(LOG, &quot;>>$LOGDIR/$LOGFILE&quot;) || print &quot;Unable to open Logfile. $!\n&quot;;
        print LOG &quot;$_&quot;;
        close(LOG);
        if (/^A .*(DN((7\d)|(15)|(16))\d{2}) .*(\d{7,7})/) {
           $DN = $1;
           $PAC = $2;
           if( $DN =~ DN((7\d)|(15)|(16))\d{2}){
                if (defined $AUTHCODES{$PAC} ){
                  ($NAME,$CLASS,$EXTDN) = split(',', $AUTHCODES{$PAC} );
                  if ($CLASS ne (&quot;T&quot;|&quot;W&quot;)){ 
                  open(MAIL, &quot;| mail -s MAXWELL-AUTHCODE-ALERT pacalert&quot;) || die &quot;$\n!&quot;;

                  print MAIL &quot;Call from Ext-> $DN                                \nCurrent PAC CODE Assignment:$PAC
                                \nName-> $NAME                                \nDefined As-> $CLASS                                \nExt-> $EXTDN&quot;;
                  close(MAIL);
                  #$NOW=`date +%s`;
                  #chop $NOW;
                  open(ALERT,&quot;>/root/$PAC.PAC&quot;);
                  print ALERT &quot;$PAC&quot;;
                  close(ALERT);
                  open(FTP,&quot;|/sbin/alertftp&quot;);
                  print FTP &quot;/root/$PAC.PAC\n&quot;;
                  close(FTP);
                  }
                }

           } 

        }
        next;

}

close(MAIL);
close(SERIAL);
exit;

sub rr_db {
        open(DB,$DBFILE) || die &quot;No user db file. $!\n&quot;;
        print &quot;Reading User file...\n&quot;;
        while(<DB>){
                chop;
                ($PAC,$NAME,$CLASS,$DN) = split(',',$_);
                $AUTHCODES{$PAC} = &quot;$NAME,$CLASS,$DN&quot;;

        }
close(DB);
}
 
I see a couple of minor things first.
This isn't doing what you want it to.
Code:
if ($CLASS ne (&quot;T&quot;|&quot;W&quot;)){
I assume that you want to proceed here if $CLASS is anything but 'T' or 'W'. In that case you have to do
Code:
if ($CLASS ne &quot;T&quot; and $CLASS ne &quot;W&quot;){
# Or
if ($CLASS !~ /^[TW]$/) {
Also you do need the slashes in the regular expression.
Code:
$variable =~ /<some pattern>/;
is the standard syntax for matching.

As for your other problem

It would compile, but it wouldn't work.

What does 'wouldn't work' mean? How did it not work? I'm guessing that you are not getting the correct $PAC number. You never described which sets of numbers from the input line should go into $DN and $PAC.

Here's a hint that might help you. Starting from the left, count the number of '(' up to the pattern you want captured. The number of the parenthesis that captures what you want is the same as the numbered variable that this value gets stored in. So the 7 digit number at the end of the line, which I believe is the PAC number that you are looking for, gets put into $6, not $2.

If that doesn't solve your problem then post back with a description of what isn't working and perhaps a sample data line with an example of what you want extracted from the line.

jaa
 
Justice,
Sorry about that, I had thought I had tacked sample data on the bottom of the message, but I can see that I had forgotten to do so.

Here is some, albiet a little late: A is the line I'm looking for, ignore any line starting with another letter.
Code:
A 127 00 DN7144  T021023 10/26 14:53 7326935

A 000 00 DN2235  T021022 10/26 14:54 6591235

N 001 00 A003025 A001070 10/26 14:54 00:00:04 A 39111001556

A 000 00 DN1535  T022022 10/26 14:54 8592565

N 002 00 A001067 DN3806  10/26 14:54 00:00:04

As for it's not working, again, I realize that the statement was a little, um... lacking. :)

When it complied, it didn't appear that the PAC code was being matched to the Pattern I was testing against in the file. So your guess is correct.

I understand what your saying about the ( being the 6th one, but since the first 5 are grouped, wouldn't it mean the second pattern is counted as the 2nd one?

If not, would that mean if the line had a 16xx or a 15xxx, that $DN would not be assigned a value, because it would the 4t and 5th values? and I'm only assigning $1 to DN.

I guess the third possiblitity is, The first group is being counted as $1 because of the first (, but PAC is still the 6th (, because of the fact that it is just the 6th (, it doesn't matter that it's only the 2nd pattern.

Actually, that last possiblity makes sense. oOoh, scary.

Ok, I'll give it a shot on Monday with $6. I've almost conviced myself that it will work. I'll post back either way.

Mike
 
That was it, the $2 should have been $6. Thanks alot guys!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top