user803271
user803271

Reputation: 115

Check if multiple lines exist in text file

Using Perl I would like to check if the two lines highlighted below exist in a text file . Each line is preceded by a tab.

CF=CFU-ALL-PROV-NONE-YES-NO-NONE-YES;
CF=CFB-ALL-PROV-NONE-YES-YES-NONE-YES;
***CF=CFU-TS10-ACT-NONE-YES-NO-NONE-YES;***
CF=CFNRY-ALL-PROV-NONE-YES-YES-NONE-YES;
CF=CFNRC-ALL-PROV-NONE-YES-NO-NONE-YES;
***CF=CFB-TS10-ACT-NONE-YES-NO-NONE-YES;***
CF=CFD-TS10-REG-9124445544-YES-YES;

I am using the following if statement but it is not matched

if (/\t*CF=(CFU-TS10-ACT-(NONE|\d+))/  && /\t*CF=(CFB-TS10-ACT-(NONE|\d+))/)
{       
 say "this case is found here .....";
}

What am I doing wrong ?

Edited This is the program I wrote :-

#!/usr/bin/perl 
use strict;
use warnings;
use feature 'say';

my $HSSIN='D:\testproject\HSS-export-test-run-small.txt';
my $ofile = 'D:\testproject\HSS-output.txt';
open (INFILE, $HSSIN) or die "Can't open input file";
open (OUTFILE,"> $ofile" ) or die "Cant open file"; 
my $add;
my $MSISDN;

my $line; 


 sub callForwardingsCF()

    {

 if (/\t*CF=(CFU-TS10-ACT-(NONE|\d+))/  && /\t*CF=(CFB-TS10-ACT-(NONE|+\d+))/)

    {

   say "this case is found here .....";


    } 

    } # end sub callForwardingsCFD



while (<INFILE>) 
{
    if (/<SUBEND/)  
    {
        say "SUBEND found";
        #$line = $1 if /^\s*MSISDN=(\d+);/;
        print OUTFILE "processSingle UpdateCommand GSUB MKEY $line";
        print OUTFILE "\n";

    }

    if ($_ =~ /^\t*MSISDN=(\d+);/) 
    {   #find MSISDN in file global search

     say "STARTER MSISDN is $1";  
     $MSISDN = $1;  
     $add = $1;     
     $line = "$1";   #group 1 

    }  

callForwardingsCF();  #callForwardings 

}

close INFILE; close OUTFILE;

Example of a record in the input file

<BEGINFILE>
<SUBBEGIN
    IMSI=232191400029053;
    MSISDN=4369050064401;
    DEFCALL=TS11;
    CURRENTNAM=BOTH;
    CAT=COMMON;
    TBS=TS11&TS12&TS21&TS22;
    VLRLIST=10;
    SGSNLIST=10;
    SMDP=MSC;
    CB=BAOC-ALL-PROV;
    CB=BOIC-ALL-PROV;
    CB=BOICEXHC-ALL-PROV;
    CB=BICROAM-ALL-PROV;
    CW=CW-ALL-PROV;
    CF=CFU-ALL-PROV-NONE-YES-NO-NONE-YES-65535-NO-NO-NO-NO-NO-NO-NO-NO-NO-NO;
    CF=CFB-ALL-PROV-NONE-YES-YES-NONE-YES-65535-NO-NO-NO-NO-NO-NO-NO-NO-NO-NO;
    CF=CFU-TS10-ACT-NONE-YES-NO-NONE-YES-65535-YES-YES-NO-NO-NO-NO-NO-NO-NO-NO;
    CF=CFNRY-ALL-PROV-NONE-YES-YES-NONE-YES-65535-NO-NO-NO-NO-NO-NO-NO-NO-NO-NO;
    CF=CFNRC-ALL-PROV-NONE-YES-NO-NONE-YES-65535-NO-NO-NO-NO-NO-NO-NO-NO-NO-NO;
    CF=CFB-TS10-ACT-NONE-YES-NO-NONE-YES-65535-YES-YES-NO-NO-NO-NO-NO-NO-NO-NO;
    CF=CFD-TS10-REG-91436903000-YES-YES-25-YES-65535-YES-YES-NO-NO-NO-YES-YES-YES-YES-NO;
    TCSISTATE=YES;
    OCSISTATE=YES;
    CONTROL=SUB;
    WPA=0;
    GS=HOLD&MPTY&ECT&CLIR&CLIP;
    CLIRES=TEMPALLOW;
    CLIPOC=NO;
    OCSI=10;
    CFSMS=ACT-10-914366488325207-YES-YES-NO-NO-NO;
    ARD=PROV;
    SUBRES=ALLPLMN;
    IST_ALERT_TIMER=120;
    IST_ALERT_RESPONSE=2;
    SUB_AGE=0;
    MIMSI=240076400029053-ONELIVE-2-2-1-0-0;
    MIMSI=232191400029053-ONELIVE-1-1-1-0-0;
    SID=2805158185721065;
    MCSISTATE=YES;
    CLRBSG=CLIP-YES-NO-NO-NO-NO;
    UPLCSLCK=NO;
    UPLPSLCK=NO;
    DEFOFAID=10;
    EPS_PROFILE_ID=1;
    TGPPAMBRMAXUL=50000000;
    TGPPAMBRMAXDL=150000000;
    ARD_EXT=NULL-NULL-NULL-N3GPPNOTALLOWED;
    FRAUDTPL_ID=10;
    HLR_INDEX=1;
    LTEAUTOPROV=NO;
    PSSER=1-1-10-1-NONE-DYNAMIC-00000000;
    EPSSER=1-10-10-1-NONE-DYNAMIC-00000000-1;
    MPS=NO;
<SUBEND

Thanks, Graham

Upvotes: 0

Views: 700

Answers (3)

james28909
james28909

Reputation: 574

#$/ = ""; #without paragraph mode

open my $file, '<', 'data_file';
binmode $file; 

while(<$file>){
        print $_  if ( $_ =~ /\s+CF=CFU-TS10-ACT-NONE-YES-NO-NONE-YES-\d+-YES-YES-NO-NO-NO-NO-NO-NO-NO-NO;/ || 
                       $_ =~ /\s+CF=CFB-TS10-ACT-NONE-YES-NO-NONE-YES-\d+-YES-YES-NO-NO-NO-NO-NO-NO-NO-NO;/  );
    }

EDIT:

OR, you can do it in paragraph mode if conditions allow it.

$/ = ""; 

open my $file, '<', 'data_file';
binmode $file;

while(<$file>){
    (undef, $first) = split (/\s+(CF=CFU-TS10-ACT-NONE-YES-NO-NONE-YES-\d+-YES-YES-NO-NO-NO-NO-NO-NO-NO-NO;)/, $_);
    (undef, $second) = split(/\s+(CF=CFB-TS10-ACT-NONE-YES-NO-NONE-YES-\d+-YES-YES-NO-NO-NO-NO-NO-NO-NO-NO;)/, $_ );
     print $first . "\n" . $second;
}

Code is tested and seems to work fine with supplied data.

Also, those are not tabs "\t" ... those are spaces "\s+" preceding those lines. Best thing is to learn your data set before you try to parse it ;)

Upvotes: 1

nlu
nlu

Reputation: 1963

Per default regexes match linewise.

So if you were trying to match an input that contains multiple lines, you would have to use one of the modifiers that allows the regex to match the entire string.

See the the perl regex documentation - the chapter "Modifiers".

Then you should add the s modifiler and change your if statement to:

if ( /\t*CF=(CFB-TS10-ACT-(NONE|\d+))/s &&
     /\t*CF=(CFU-TS10-ACT-(NONE|\d+))/s ) {
   say "found";
}

If you read linewise you will never have both of your regexes match for the same line, so you would need to do your regexes seperately as already suggested by the other answer.

Upvotes: 1

AnFi
AnFi

Reputation: 10903

Typically perl processes file "line by line".
Try something like sample script below:

my($line1,$line2);
while(<STDIN>) {
  $line1=$_ if /\t*CF=(CFU-TS10-ACT-(NONE|\d+))/
  $line2=$_ if /\t*CF=(CFB-TS10-ACT-(NONE|\d+))/
  if( $line1 and $line2 ) {  
    say "this case is found here .....";
    last; # skip processing remaning lines
  }
}

Alternatively you may "slurp" whole file into one scalar variable.

Upvotes: 0

Related Questions