在perl中找到模式后删除文件中的行

时间:2014-11-06 00:44:55

标签: perl file-io

示例输入tcl文件内容:

# Bind
 ::d::autoBindmap $intfcName 

-------------so many other lines------------------------------
############ Power information for vss #####################
#----------------------------
 #pg_vss s100
#----------------------------
 #Add pg_vss_dl interface
set  intfcName pg_vss 1.0 s 100

 #Add Verilog port binding for vss
 ::d::autoBindmap $module pg_vss $intfcName
{
 VSSGND vss_dl;
 }

############ Power information for vdd #####################
#----------------------------
 #pg_vdd s100
#----------------------------
 #Add pg_vdd_dl interface
set  intfcName pg_vdd 1.0 s 100

 #Add Verilog port binding for vss
 ::d::autoBindmap $module pg_vdd $intfcName
{
 VDD vss_dl;
 }

-----------------------so many other lines-------------------------------

 #write component 
 ::d::writeLib $module

目的: 我有一个数组(由这里未提供的代码的其他部分生成)由字符串组成。数组内容正在针对不同文件进行更改。如果使用模式匹配在文件的特定行中找到任何数组元素,我需要删除之后的11行和文件中的行本身。

问题: 此更改应在当前文件中进行。所以,我尝试在读写模式下打开文件。但是,我看到垃圾被打印出来了。

例如(参见上面的输入tcl文件):

我需要删除所有行(在本例中为11),直到找到“$ rpow的电源信息”(例如$ rpow为vss)之后的“}”,并删除行本身,其中vss是一个元素我的remove_power_list数组。所有数组元素都应该删除。

请问有人可以解决这个问题吗?

此处仅显示有问题的代码:

#####Used help of StackOverflow member Praveen to come up with this code

my $rpow;

for $rpow (@remove_power_list) {

        my $bf_content;
        open $bf_content, '+<', $bf_bind;

           my $count = 0;

        while (<$bf_content>){

                  if($_ =~ /Power\s+information\s+for\s+$rpow\s+/) {
                $count = $. + 11; 
                }   

                else    
         {   
        if($count != 0 && $. < $count)
          {   

            }   
        elsif($count != 0 && $. == $count)
          {   
             $count =0; 
              }   
         else
          {   
             print $bf_content $_; 
              }   
         }

        }             
close $bf_content;
}

注意:我无法安装cpan File :: Slurp。

预期示例输出:

 # Bind
 ::d::autoBindmap $intfcName 

-------------so many other lines------------------------------

############ Power information for vdd #####################
#----------------------------
 #pg_vdd s100
#----------------------------
 #Add pg_vdd_dl interface
set  intfcName pg_vdd 1.0 s 100

 #Add Verilog port binding for vss
 ::d::autoBindmap $module pg_vdd $intfcName
{
 VDD vss_dl;
 }

-----------------------so many other lines-------------------------------

1 个答案:

答案 0 :(得分:0)

@aa_electronics:我相信你的剧本中存在很多问题。因此,根据您的要求,我编写了一个perl代码。看看:

InputFile:(input.txt)

 # Bind
     ::d::autoBindmap $intfcName 


    ############ Power information for vss #####################
    #----------------------------
     #pg_vss s100
    #----------------------------
     #Add pg_vss_dl interface
    set  intfcName pg_vss 1.0 s 100

     #Add Verilog port binding for vss
     ::d::autoBindmap $module pg_vss $intfcName
    {
     VSSGND vss_dl;
     }

    ############ Power information for vdd #####################
    #----------------------------
     #pg_vdd s100
    #----------------------------
     #Add pg_vdd_dl interface
    set  intfcName pg_vdd 1.0 s 100

     #Add Verilog port binding for vss
     ::d::autoBindmap $module pg_vdd $intfcName
    {
     VDD vss_dl;
     }


     #write component 
     ::d::writeLib $module

<强>代码:

use strict;
use warnings;   

my $infile = $ARGV[0];
my $outfile = "out.txt";

open my $fh,'<',$infile or die "Couldnt open the file $infile:$!" ; 
open my $out,'>',$outfile or die "Cannot write to the file $!"; 
my $count = 0;
my $var = 0;
my @final=();

my @remove_power_list = ("vcchg","vccl","vss");

   while(<$fh>)
        {
            #chomp;
            foreach my $rem(@remove_power_list) {
                $var++;
        my $line = 'Power\s+information\s+for\s+' . "$rem";
          if($_ =~ /$line/g)
           {
             $count = $. + 11;
            }
          else      
          {
             if($count != 0 && $. < $count)
              {
                 }
             elsif($count != 0 && $. == $count)
                {
                  $count =0;
                  }         
             else
              {
                if($var ==1)
                 {
                 push(@final,$_);
                  }
                }     
            }
        }  
      $var=0;  
    }

foreach my $rem(@remove_power_list)
 { 
 foreach my $res (@final)
   {
        my $line = 'Power\s+information\s+for\s+' . "$rem";
          if($res =~ /$line/g)
           {
           $res =~ s/$res//isg;
            }          
        }       
     } 

foreach my $finalval (@final)
 {
     print $out $finalval;
    }          
 close($fh);       
close($out);

输出:(out.txt)

# Bind
     ::d::autoBindmap $intfcName 


    ############ Power information for vss #####################

    ############ Power information for vdd #####################
    #----------------------------
     #pg_vdd s100
    #----------------------------
     #Add pg_vdd_dl interface
    set  intfcName pg_vdd 1.0 s 100

     #Add Verilog port binding for vss
     ::d::autoBindmap $module pg_vdd $intfcName
    {
     VDD vss_dl;
     }


     #write component 
     ::d::writeLib $module