2017-08-26 64 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不匹配,则打印缓冲区并打印行。 –