2014-11-06 50 views
0

示例輸入TCL文件內容後發現:刪除線在一個文件中,圖案是在Perl

# 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檔案::嘟嘟地喝。

預期輸出示例:

# 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------------------------------- 
+2

你有一些明顯的親與你的腳本混淆。我看到的最大的一個是,你在for循環中不斷重新打開$ outfile,並且在重寫模式下,至多意味着輸出文件中會有最後一行輸出。但是你沒有告訴我們你遇到了什麼具體問題,所以很難解決你的問題。 – Flimzy 2014-11-06 03:24:05

+0

@Flimzy,問題是我無法使用我正在使用的模式匹配和數組循環技術刪除文件的所有內容。另外,正如你所提到的,當我按照Praveen的建議嘗試刪除固定數量的行時,我會看到所有最後一行被截斷。所以,讓我在這裏重寫我的問題:我需要根據與remove_power_list數組元素的匹配從輸入tcl文件中刪除行。我需要在找到「Power information for $ p」後刪除11行。 $ p可以是任何東西。如果remove_power_list有它,那麼我需要刪除11行和那行。 – 2014-11-06 19:29:39

+0

@Flimzy:例如(見上面輸入的tcl文件):我需要刪除所有行(本例中爲11行),直到找到「$ rpow的電源信息」(例如$ rpow爲vss)之後的「}」 ,線路本身被刪除。 「vss」是我的remove_power_list數組的一個元素。這個刪除應該發生在所有數組元素上。 因此,我沒有選擇,只能在陣列的「for循環」內以讀/寫模式打開和關閉文件。它在寫文件的同時在文件中打印垃圾。我正在使用用戶Pradeep的代碼,並進行了一些修改。 – 2014-11-06 21:25:29

回答

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 
+0

謝謝你的回答。但是,我忘記提及remove_power_list數組基於我的巨大腳本中的其他代碼不斷變化。那麼,我們可以在while語句之前使用for循環來匹配那些行嗎?另外,我需要刪除「Power信息$ p」($ p是vss),同時刪除這11行。我也沒有提到這一點。我想我可以刪除,如果我不把打印語句放在「if」語句大括號中。 – 2014-11-06 18:00:22

+0

對不起,我正忙於其他事情。修改了代碼。看一看。 – Praveen 2014-11-08 18:36:05

+0

謝謝。這工作。 – 2014-11-10 21:20:10

相關問題