用于grep的Perl脚本始终会阻止并打印指定的行

时间:2019-02-14 06:27:38

标签: perl awk sed grep

我需要获取文件,逐行读取并搜索always_ff块。 如果存在always_ff,那么我需要从找到的always_ff块内

打印特定行
use strict;
use warnings;

for my $file ('*.sv')
{
   open my $fh, "<", $file or die $!;
   while (<$fh>) {
     print scalar <$fh> if /begin/;
   }
}

该文件具有:

always_ff @(negedge clk )
    begin
       if (!clk)
       begin
          p1 <= 1'b0;
       end
       else
       begin
         p1 <= disable_ff;
       end
    end

always_ff @(negedge clk)
    begin
       if (!clk)
       begin
          p2<= enable;
       end
       else
       begin
          p2 <= disable_ff;
       end
    end

预期结果:

p1 <= disable_ff
p2<= enable
p2 <= disable_ff;

实际结果即将到来:

if (!clk)
  p1 <= disable_ff;

1 个答案:

答案 0 :(得分:2)

您可能应该将range运算符与模式的开头和结尾相匹配。查看您的输入数据,我建议:

  • 开始:匹配“ always_ff”和空格,即/always_ff\s+/
  • end:空行,即/^\s*$/
  • 在该块中:打印带有赋值的行,即/<=/

引用perlop

  

在标量上下文中,..返回一个布尔值。运算符是双稳态的,就像触发器一样,...只要其左操作数为false,它就是false。一旦左操作数为true,则范围运算符将保持为true,直到右操作数为true,此后范围运算符将再次变为false。

类似这样的东西

#!/usr/bin/perl
use warnings;
use strict;

while (<DATA>) {
    if (/always_ff\s+/../^\s*$/) {
        print if /<=/;
    }
}

exit 0;

__DATA__
always_ff @(negedge clk )
    begin
       if (!clk)
       begin
          p1 <= 1'b0;
       end
       else
       begin
         p1 <= disable_ff;
       end
    end

always_ff @(negedge clk)
    begin
       if (!clk)
       begin
          p2<= enable;
       end
       else
       begin
          p2 <= disable_ff;
       end
    end

测试输出:

$ perl dummy.pl
          p1 <= 1'b0;
         p1 <= disable_ff;
          p2<= enable;
          p2 <= disable_ff;

对于您读取*.sv文件的用例,将我的测试代码中的<DATA>替换为<STDIN>,并使用以下shell命令行:

$ cat *.sv | perl script.pl