检查文本文件中是否存在多行

时间:2018-03-26 11:58:56

标签: regex perl if-statement logic perl-module

使用Perl我想检查下面突出显示的两行是否存在于文本文件中。每行前面都有一个标签。

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;

我正在使用以下if语句,但它不匹配

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

我做错了什么?

被修改 这是我写的程序: -

#!/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 

}

关闭INFILE; 关闭OUTFILE;

输入文件中的记录示例

<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

谢谢, 格雷厄姆

3 个答案:

答案 0 :(得分:1)

默认正则表达式按行匹配。

所以如果你试图匹配包含多行的输入,你必须使用一个允许正则表达式匹配整个字符串的修饰符。

请参阅the perl regex documentation - 章节&#34;修饰符&#34;。

然后你应该添加s modifiler并将你的if语句改为:

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

如果你逐行阅读,你将永远不会让你的两个正则表达式匹配同一行,所以你需要像其他答案所建议的那样单独进行你的正则表达式。

答案 1 :(得分:1)

#$/ = ""; #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;/  );
    }

编辑:

或者,如果条件允许,您可以在段落模式下执行此操作。

$/ = ""; 

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;
}

代码经过测试,似乎与提供的数据一起正常工作。

此外,这些不是标签&#34; \ t&#34; ......那些是空间&#34; \ s +&#34;在这些线之前。最好的办法是在尝试解析之前学习数据集;)

答案 2 :(得分:0)

通常perl处理文件&#34;逐行&#34;。
尝试下面的示例脚本:

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
  }
}

或者你可以&#34; slurp&#34;将整个文件转换为一个标量变量。