2017-08-26 109 views
0

這裏我試圖將文件從# start data分割爲# end data,如果字符串'Pen'或'Laptop'存在,則代碼應該繼續寫入文件,如果不是,則應該寫入文件進入輸出文件。perl中的文本文件操作

Input 
     # start data a1 
     Data1 Book 1234 
     Data1 Pen 54635 
     Data1 Laptop 4567 
     Data1 Lens 6473 
     # end data a1 
     # start data a2 
     Data2 Book 1234 
     Data2 Box 54635 
     Data2 Card 4567 
     Data2 Lens 6473 
     # end data a2 

Expected ouput 

     # start data a2 
     Data2 Book 1234 
     Data2 Box 54635 
     Data2 Card 4567 
     Data2 Lens 6473 
     # end data a2 

守則snipppet使用:

#!/usr/local/perl 
use warnings; 
use strict; 
open(filein, "<Input.txt"); 
open(fileout, ">ouput.txt"); 
my @array; 
my $strt =qr/^#\sstart\sdata/; 
my $end=qr/^#\send\sdata/; 
while(<filein>) 
{ 
    @array= split(/$strt/../$end/,$_); 
    foreach my $i(@array) 
    { 
     if($i =~ /Pen|Laptop/) 
     { 
      next; 
     } 
     else 
     { 
      print fileout "$_"; 
     } 
    } 
} 
close(filein); 
close(fileout); 



Obtained Output from the above snippet 
    # start data a1 
    Data1 Book 1234  
    Data1 Book 1234 
    Data1 Pen 54635  
    Data1 Laptop 4567  
    Data1 Lens 6473 
    # end data a1   
    # start data a2  
    Data1 Book 1234  
    Data1 Book 1234 
    Data1 Box 54635 
    Data1 Box 54635 
    Data1 Card 4567  
    Data1 Card 4567 
    Data1 Lens 6473 
    # end data a2  
+0

嗨,你已經證明你的預期產出,而不是你的輸出電流,或你認爲問題是。你可以[編輯]你的問題,以清楚你需要什麼? – IMSoP

+0

嗨,我已經更新了我從我的代碼得到的輸出。我認爲這主要是我用過的正則表達式的問題。請建議 – user8450886

回答

0

以下腳本會給你幾乎所需的輸出

#!/usr/bin/perl 

open (FH,"text.txt") || die "Not able to open text.txt $!"; 
@values=(); 
while($line = <FH>) 
{ 
     unless($line=~/end data/) 
     { 
       chomp($line); 
       push(@values,$line); 
       next; 
     } 

     if (grep{ $_ =~ /Pen|Laptop/i} @values) 
     { 
       @values=(); 
     } 
     else 
     { 
       open(FH2,">>newtext.txt") || die "Not able to open newtext.txt $!"; 
       foreach (@values) 
       { 
         print FH2 "$_\n"; 
       } 
       close(FH2); 
       @values=(); 
     } 
} 
close(FH); 

內容的text.txt的: - 在newtext.txt中

# start data a1 
Data1 Book 1234 
Data1 Pen 54635 
Data1 Laptop 4567 
Data1 Lens 6473 
# end data a1 
# start data a2 
Data2 Book 1234 
Data2 Box 54635 
Data2 Card 4567 
Data2 Lens 6473 
# end data a2 
# start data a3 
Data2 Book 1234 
Data2 Box 54635 
Data2 Lamp 4567 
Data2 Lens 6473 
# end data a3 

輸出: -

# start data a2 
Data2 Book 1234 
Data2 Box 54635 
Data2 Card 4567 
Data2 Lens 6473 
# start data a3 
Data2 Book 1234 
Data2 Box 54635 
Data2 Lamp 4567 
Data2 Lens 6473 
1

range operator不能用來作爲參數傳遞給split - 它需要一個/PATTERN/

我無法解釋你從代碼中得到的結果與不正確的分割用法。它真的很怪異!

關於你的代碼的一些意見。

你是using嚴格和警告。在代碼開發過程中發現錯誤的一個好習慣

您應該使用首選的3參數來打開文件,寧願使用詞法文件句柄$in來使用裸號文件句柄filein。並且應該經常檢查文件是否打開沒有錯誤,. . . or die $!

open(filein, "<Input.txt");更好的寫作 - open my $in, '<', 'Input.txt' or die $!;

print fileout "$_";引號周圍$_被unneccesary,只是打印,讓你想用一些perl的功能輸出的$_變量

一個工作程序,可能會(下) -

open my $out, '>', 'file2' or die $!; 

{ 
    local $/ = "# end data\n"; 
    while (<$in>) { 
     print $out $_ unless /Pen|Laptop/; 
    } 
} 

默認輸入記錄分隔符是\n。在這裏,我將它定義爲(本地塊),以"# end data\n"

(創建一個塊是不是在這種情況下,必要的,但通常應該這樣做是當塊超出範圍,輸入記錄分隔符恢復它的先前值 - 這裏的\n默認值僅local使用在塊的範圍)

因此,這一計劃中的行,而行塊一次讀取指定的值,(因爲$/分離器是"# end data\n"而不是"\n"

+0

嗨感謝您的輸入。但我有一個更多的疑問,我改變了我的輸入格式。然後我嘗試使用給出的代碼,但它不打印任何輸出。我用過的表達式是(本地$/=「#結束數據(。*)\ n」在上面的輸入描述中更改輸入請注意 – user8450886

+0

「__I改變了我的輸入格式_」不要這樣做 - 它會導致我的示例不正確。如果緩衝區中的行與Pen或Laptop不匹配,則打印緩衝區並打印行。 –