in reply to Grouped Regular Expression not set assign default value

Hello gbwien,

Maybe this is not the best solution to your problem but it could be a point of start:

#!/usr/bin/perl use strict; use warnings; use feature 'say'; open (my $fhIn, '<', "in.txt") or die "Can not open 'in.txt': $!"; open (my $fhOut, '>', "out.txt") or die "Can not open 'out.txt': $!"; my %hash; my $count = 0; while (<$fhIn>) { chomp; if (/<SUBBEGIN/) { $count = 1; } elsif (/<SUBEND/) { $count = 0; } elsif ($count) { my @tmp = split /=/; chop $tmp[1]; if (/MSISDN/) { $hash{MSISDN} = $tmp[1]; } elsif (/ODBIC/) { $hash{ODBIC} = $tmp[1]; } elsif (/ODBOC/) { $hash{ODBOC} = $tmp[1]; } } if ($count == 0) { if (exists $hash{MSISDN}) { say $fhOut "Update Command <".$hash{MSISDN}.">,".$hash{ODBIC}. +",".$hash{ODBOC}.""; } else { say $fhOut "Update Command MSISDN=notSet,".$hash{ODBIC}.",".$h +ash{ODBOC}.""; } delete $hash{MSISDN}; delete $hash{ODBIC}; delete $hash{ODBOC}; } } close ($fhIn) or warn "Could not close 'in.txt': $!"; close ($fhOut) or warn "Could not close 'out.txt': $!"; __END__ $ cat out.txt Update Command <123476789678>,BIC,BAOC Update Command MSISDN=notSet,BIC,BAOC

If there is something that you can not understand let me know. Maybe you will find other ways to approach your problem at Getting lines in a file between two patterns.

Hope this helps, BR.

Seeking for Perl wisdom...on the process of learning...not there...yet!

Replies are listed 'Best First'.
Re^2: Grouped Regular Expression not set assign default value
by gbwien (Sexton) on Feb 21, 2018 at 16:33 UTC

    Hi thanos1983 Thank you for your help, I extended your solution to check for these fields CF and ODB fields which I output to a comma separated file when set and not set. It works fine except for CF fields, I think this is because these lines are not unique in the file. For CF lines example I would like to set CfuNotSet if the line CFU-ALL-PROV-NONE is not found, CFbNoSet if the line CFB-ALL-PROV-NONE is not found and so on. Eventually I would also like to check for CB fields. I have done this without a hash with the help from Laurent_R but I would like to learn your solution too

    This piece of code seems ok code

    #build up the hash CF if (/CF/){ $hash{CF} = $tmp[1]; #say $hash{CF}; }

    I think the problem is here

    #PROBLEM CODE check CF fields need to accommodate for multiple CF l +ines if (exists $hash{CF}) { $add = $hash{CF}; $line .= ",$add"; }
    <BEGINFILE> <SUBBEGIN IMSI=11111111111111; MSISDN=431234567893; CB=BAOC-ALL-PROV; CB=BOIC-ALL-PROV; CB=BOICEXHC-ALL-PROV; CB=BICROAM-ALL-PROV; IMEISV=4565676567576576; 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-N +O-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=CFD-TS10-ACT-91436903000-YES-YES-25-YES-65535-YES-YES-NO-NO-NO- +YES-YES-YES-YES-NO; ODBIC=BAIC; ODBOC=BAOC; ODBROAM=ODBOHC; ODBPRC=ENTER; ODBPRC=INFO; ODBPLMN=NONE; ODBPOS=NOBPOS-BOTH; ODBECT=OdbAllECT; ODBDECT=YES; ODBMECT=YES; ODBPREMSMS=YES; ODBADULTSMS=YES; <SUBEND <SUBBEGIN IMSI=11111111111133; MSISDN=431234567899; 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-N +O-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=CFU-TS10-ACT-914369050045021-YES-NO-NONE-YES-65535-YES-YES-NO-N +O-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; ODBIC=BICCROSSDOMESTIC; ODBOC=BAOC; ODBROAM=ODBOH; ODBPRC=INFO; ODBPLMN=PLMN1 ODBPLMN=PLMN3; ODBPOS=NOBPOS-BOTH; ODBECT=OdbAllECT; ODBDECT=YES; ODBMECT=YES; ODBPREMSMS=NO; ODBADULTSMS=YES; <SUBEND

    If I understand it correctly you split up the lines of the record based on the equals sign. This seems to work fine until CF entries are encountered

    #!/usr/bin/perl use strict; use warnings; use feature 'say'; use Data::Dumper; my $HSSIN='D:\testproject\HSS-export.txt'; my $ofile = 'D:\testproject\HSS-output-withhash.txt'; open (INFILE, $HSSIN) or die "Can't open input file"; open (OUTFILE,"> $ofile" ) or die "Cant open file"; my %hash; my $count = 0; my $add; my $line; while (<INFILE>) { chomp; next if /^<ENDFILE>/; next if /^<BEGINFILE>/; if (/<SUBBEGIN/) { $count = 1; } elsif (/<SUBEND/) { $count = 0; } elsif ($count) { my @tmp = split /=/; chop $tmp[1]; #build up the hash CF if (/CF/){ $hash{CF} = $tmp[1]; #say $hash{CF}; } if (/MSISDN/) { $hash{MSISDN} = $tmp[1]; } if (/ODBIC/) { $hash{ODBIC} = $tmp[1]; } elsif (/ODBOC/) { $hash{ODBOC} = $tmp[1]; } elsif (/ODBROAM/) { $hash{ODBROAM} = $tmp[1]; } } if ($count == 0) { #check MSISDN field if (exists $hash{MSISDN}) { $line = $hash{MSISDN}; #'say OUTFILE $line; #say OUTFILE "Update Command <".$hash{MSISDN}.">,".$hash{ODBIC +}.",".$hash{ODBOC}.",".$hash{ODBROAM}.""; } else { #say OUTFILE "Update Command MSISDN=notSet,".$hash{ODBIC}.",".$ +hash{ODBOC}.""; $line = 'MSISDN=notSet'; } #PROBLEM CODE check CF fields need to accommodate for multiple CF l +ines if (exists $hash{CF}) { $add = $hash{CF}; $line .= ",$add"; } #check ODBIC field if (exists $hash{ODBIC}) { $add = $hash{ODBIC}; $line .= ",$add"; } else { $add = 'ODBICnotSet'; $line .= ",$add"; } #check ODBOC field if (exists $hash{ODBOC}) { $add = $hash{ODBOC}; $line .= ",$add"; } else { $add = 'ODBOC notSet'; $line .= ",$add"; } #check ODBROAM field if (exists $hash{ODBROAM}) { $add = $hash{ODBROAM}; $line .= ",$add"; } else { $add = 'ODBROAM notSet'; $line .= ",$add"; } #check hash for ODBOC->BAOC is not set set it to ODBOC->BAOCnotSet delete $hash{MSISDN}; delete $hash{ODBIC}; delete $hash{ODBOC}; delete $hash{ODBROAM}; delete $hash{CF}; #build up line say OUTFILE $line; } } close INFILE; close OUTFILE;

      Hello again gbwien,

      I am not 100% sure what is the expected output from your description. I took a guess and I put together an example based on the new input and what I think you mean.

      Having said that I think the only modifications that you need to add is:

      I have not update the concatenation of the string output since I do not know what is the actual output that you are looking for.

      In case that this is not the expected way the string should behave, provide an desired output sample so I can understand approximately based on input which fields you want to keep and which you want to skip.

      Hope this helps, BR.

      Seeking for Perl wisdom...on the process of learning...not there...yet!

        Hi thanos1983 An example of an input file is below, the file starts with <BEGINFILE> and ends with <ENDFILE>. To accommodate for this I added to your while loop

        chomp; next if /^<ENDFILE>/; next if /^<BEGINFILE>/; next if (/<BEGINFILE>/);
        <BEGINFILE> <SUBBEGIN IMSI=0000000000000; MSISDN=4411287879987; DEFCALL=TS11; CURRENTNAM=BOTH; CAT=COMMON; TBS=TS11&TS12&TS21&TS22; VLRLIST=10; SGSNLIST=10; MSC=445454578142; SGSN=44546578751; SMDP=MSC; CB=BAOC-ALL-PROV; CB=BOIC-ALL-PROV; CB=BOICEXHC-ALL-PROV; CB=BICROAM-ALL-PROV; IMEISV=000011222554545; 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-N +O-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=CFD-TS10-ACT-9112345678-YES-YES-25-YES-65535-YES-YES-NO-NO-NO-Y +ES-YES-YES-YES-NO; CONTROL=SUB; WPA=0; GS=HOLD&MPTY&ECT&CLIR&CLIP; CLIRES=TEMPALLOW; CLIPOC=NO; ARD=PROV; SUBRES=ALLPLMN; IST_ALERT_TIMER=120; IST_ALERT_RESPONSE=2; SUB_AGE=0; UPL_TIME=1447410859; PURGE_TIME_ATMSC=1505118714; GPRSUPL_TIME=1446458542; PURGE_TIME_ATSGSN=1447506399; MIMSI=564567467234544-ONELIVE-1-1-1-0-0; MIMSI=123245748722558-ONELIVE-2-2-1-0-0; SID=64672546767; UNRI=NO; UNRR=100; URRP_MME=REACHABLE; URRP_SGSN=NOT_REACHABLE; 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; SUB_DYN_EPS_ID=1; MMEHOST=graz1.mme.epc.mnc003.mcc232.3gppnetwork.org; MMEREALM=epc.mnc003.mcc232.3gppnetwork.org; EPS_IMEI=866695022931980; EPS_IMEISV=00; MMEFEATURELIST=ALL_APN-HPLMN_APN-VPLMN_APN-NULL-NULL-NULL-NULL-NUL +L-NULL-REGSUB-TRACE-NULL-NULL-NULL-NULL-NULL-NULL-NULL-NULL-NULL-NULL +-NULL-NULL-NULL-NULL-NULL-TADS_DATA_RETR; SGSNFEATURELIST=NULL-NULL-NULL-NULL-NULL-NULL-NULL-NULL-NULL-NULL- +NULL-NULL-NULL-NULL-NULL-NULL-NULL-NULL-NULL-NULL-NULL-NULL-NULL-NULL +-NULL-NULL-NULL; MMEULRFLAG=SING_REG_IND-S6AORS6D_IND-SKIP_SUBDATA-NULL-NULL-NULL-P +S_LCS_NOTSUPP; SGSNULRFLAG=NULL-NULL-NULL-NULL-NULL-NULL-NULL; MMETIMESTAMP=1447506399; S4SGSNTIMESTAMP=0; 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; ODBIC=BAIC; ODBOC=BAOC; ODBROAM=ODBOHC; ODBPRC=ENTER; ODBPRC=INFO; ODBPLMN=NONE; ODBPOS=NOBPOS-BOTH; ODBECT=OdbAllECT; ODBDECT=YES; ODBMECT=YES; ODBPREMSMS=YES; ODBADULTSMS=YES; <SUBEND <ENDFILE>

        The output should look like this for this record,couple of regex do work on the output CFU-ALL-PROV-NONE becomes CFU-ALL-PROV-1/1/1/0,CFB-ALL-PROV-NONE becomes CFNRY-ALL-PROV-1/1/1/0,,CFNRY-ALL-PROV-NONE becomes CFNRY-ALL-PROV-1/1/1/0, CFD-TS10-ACT-9112345678 becomes CFD-TS10-ACT-12345678 The ouput consists of the following values, MSISDN,CB,CF and ODB values.

        4411287879987,BAOC-ALL-PROV,BOIC-ALL-PROV,BOICEXHC-ALL-PROV,BICROAM-ALL-PROV,CFU-ALL-PROV-1/1/1/0,CFB-ALL-PROV-1/1/1/0,CFNRY-ALL-PROV-1/1/1/0,CFNRC-ALL-PROV-1/1/1/0,CFD-TS10-ACT-1/1/1/12345678,BAIC,BAOC,ODBOHC,ENTER,INFO,NONE,NOBPOS-BOTH,OdbAllECT,YES,YES,YES,YES

        Data::Dumper shows the following but CFNRC, CFB, CFU and CFNRY exist in the input file so the values for these keys are incorrect

        $VAR1 = { 'ODBOC' => 'BAOC', 'ODBIC' => 'BAIC', 'CF' => { 'CFNRC' => 'CfnrncNotSet', 'CFB' => 'CfbNotSet', 'CFD' => 'CFD-TS10-ACT-9112345678-YES-YES-25-YES-6 +5535-YES-YES-NO-NO-NO-YES-YES-YES-YES-NO', 'CFU' => 'CfuNotSet', 'CFNRY' => 'CfnrnyNotSet' }, 'MSISDN' => '4411287879987' };
        Thanks again