我如何模式匹配并继续写入新文件,直到另一个模式匹配

时间:2015-01-22 19:38:33

标签: perl

我的目标是找到并打印“big.v”文件中的所有行,从模式匹配“模块”开始直到“endmodule”为单个文件。

big.v: module test;
       <bunch of code> 
       endmodule 
       module foo;
      <bunch of code>
      endmodule

单个文件看起来像:

test.v : module test;
        ..
         endmodule

foo.v: module test1;
        ..
         endmodule

我的大部分工作都在使用:

use strict;
use warnings;

#open(my $fh, ">", $f1) || die "Couldn't open '".$f."' for writing because: ".$!;

while (<>) {
    my $line = $_; 
    if ($line =~ /(module)(\s+)(\w+)(.*)/) {
        my $modname = $3;
        open(my $fh1, ">", $modname.".v") ;
        print $fh1 $line."\n";
    ## how do i keep writing next lines to this file until following pattern
        if ($line =~ /(endmodule)(\s+)(.*)/) {  close $fh1;}
    }
}

谢谢,

1 个答案:

答案 0 :(得分:7)

有一个名为'range operator'的有用的perl结构: http://perldoc.perl.org/perlop.html#Range-Operators

它的工作原理如下:

while ( <$file> ) {
    if ( m/startpattern/ .. m/endpattern/ ) {
          print; 
    }
}

所以给出你的例子 - 我认为这应该可以解决问题:

my $output; 
while ( my $line = <STDIN> ) {
    if ( $line =~ m/module/ .. m/endmodule/ ) {
        my ( $modname ) = ( $line =~ m/module\s+(\w+)/ );
        if ( defined $modname) {
            open ( $output, ">", "$modname.v" ) or warn $!;
        } 
        print {$output} $line; 
    }
}

编辑:但是考虑到您的源数据 - 您实际上并不需要使用我不认为的范围运算符。您可以随时关闭/重新打开新的“输出”文件。这假设您可以根据“模块”行“切割”您的文件,这不一定是有效的假设。

但有点像这样:

use strict;
use warnings;

open ( my $input, "<", "big.v" ) or die $!;

my $output;
while ( my $line = <$input> ) {
    if ( $line =~ m/^\s*module/ ) {
        #start of module line found

        #close filehandle if it's open
        close($output) if defined $output;

        #extract the module name from the line. 
        my ($modulename) = ( $line =~ m/module\s+(\w+)/ );

        #open new output file (overwriting)
        open( $output, ">", "$modulename.v" ) or warn $!;
    }
    #this test might not be necessary. 
    if ( defined $output ) {
        print {$output} $line;
    }
}