我的目标是找到并打印“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;}
}
}
谢谢,
答案 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;
}
}