搜索并删除Perl中的一系列行



i无法在以下示例中删除一系列行。$ end_pattern的正则表达式似乎不匹配。

请让我知道我缺少什么。非常感谢


#!/usr/bin/perl
$begin_pattern = 'Fac.*Begin-to-search';
$end_pattern   = 'Mix.*End-to-search';
open(IN, "Input.txt") || die "Can't open file!n";
my @lines = <IN>;
foreach $line (@lines) {
    $line =~ s/^s+//; #remove leading spaces
    $line =~ s/s+$//; #remove trailing spaces
    if ($line =~ /$begin_pattern ... $end_pattern/) {
       print "$linen";
    }
    # Next, delete this range of lines
}
"Input.txt" file listed below:
-----------
 something for storing 0
No. of blocks : 0
         Filt  Nothing                  Nothing
     Fac           Y    0    Mix    0      Mix   Mix  0                  Begin-to-search
96   Fac           Y    0    60     0      900   60   0                  0                   0
806  Fac           Y    0    0      0      0     0    0                  0                   0  
     Fac A|B|C|D   Y    11   0      0      0     0    0
340  Fac A|B|C|D   Y    11   0      0      0     0    0                  0                   0
     Mix M         Y    11   Mix    Mix    0     Mix  0                  End-to-search
573  Wrn A|B|C|D   Y    11   0      0      0     0    0                  0                   0
Mix M         Y    11   60     Mix    0     60   0                  ware

带有警告的修订代码:(请参见下面的问题(


#!/usr/bin/perl
use warnings;
use strict;
my $begin_pattern = 'Fac.*Begin-to-search';
my $end_pattern   = 'Mix.*End-to-search';
open(IN, "Input.txt") || die "Can't open file!n";
my @lines = <IN>;
foreach my $line (@lines) {
    $line =~ s/^s+//;
    $line =~ s/s+$//;
    if(defined $line) { print "$line is initializedn"; }
    else { print "$line is uninitializedn"; }
    if ($line =~ /$begin_pattern/ ... /$end_pattern/) {
       print "$line";
    }
    if ($line =~ /$end_pattern/) {
        last;
    }
}

范围运算符用作

if ($line =~ /$begin_pattern/ .. $line =~ /$end_pattern/)

因此,您仅缺少第二个条件的$line =~

最好将QR运算符用于正则是REGEX,您可以在此处有效使用$_变量

use warnings;
use strict;
my $begin_pattern = qr/Fac.*Begin-to-search/;
my $end_pattern   = qr/Mix.*End-to-search/;
my $file = 'Input.txt';    
open my $fh, '<', $file or die "Can't open $file: $!";
while (<$fh>) 
{
    s/^s+//;   
    s/s+$//;
    if (/$begin_pattern/ .. /$end_pattern/) {
        print;
    }
}
close $fh;

这仅在Regexes匹配的标记之间打印

     FAC Y 0 MIX 0 MIX MIX 0开始搜索96 fac y 0 60 0 900 60 0 0 0 0806 fac y 0 0 0 0 0 0 0 0 0 0     FAC A | B | C | D Y 11 0 0 0 0 0 0340 fac a | b | c | d y 11 0 0 0 0 0 0 0 0     混合M Y 11 Mix Mix 0 Mix 0端到搜索

其他一些笔记

  • 始终use warnings;use strict;

  • 开始
  • 建议使用三词open,更好

  • 打印错误消息时,请使用$!可变量查看实际消息

  • 逐条处理文件,除非有特定原因首先读取所有行


此注释主要是汇总评论,并在问题中解释了代码的行为。

行(从原始问题上,在问题的编辑中纠正(

if ($line =~ /$begin_pattern/ ... /$end_pattern/)

确实是

if ($line =~ /$begin_pattern/ ... $_ =~ /$end_pattern/)

由于/.../总是与$_匹配,默认值。

但是,在循环foreach my $line (@lines)中,我们在迭代($line别名元素(中引入了词汇变量,然后我们 de $_;它未针对循环定义。因此,第二种模式永远不匹配,如观察到的。

请注意,从较高范围中的$_(例如,某些外循环(可能仍会在循环中看到。

解决方案是启用$_用作 foreach (@lines)的局部使用者(或在答案中, while (<$fh>),逐行读取(,然后使用

if (/$begin_pattern/ .. /$end_pattern/)

匹配与$_的匹配或设置变量并在两种情况下使用它

foreach my $line (@lines) {
    # ...
    if ($line =~ /$begin_pattern/ ... $line =~ /$end_pattern/)

请注意,.....实际上有些不同。请参阅链接文档。

实际上,也可以在循环开始时设置$_(至$line(,然后张贴的代码在站立的情况下起作用。至少可以说,这显然很尴尬。

您尝试匹配$begin_pattern$end_pattern之间的所有内容,但是您逐行读取文件,因此它永远不会匹配,因为这些模式不出现在同一行上。

分别检查每个模式,请记住您是否在想要的线路中,然后打印。

#!/usr/bin/perl
use strict;
use warnings;
my $begin_pattern = 'Fac.*Begin-to-search';
my $end_pattern = 'Mix.*End-to-search';
my $in_block = 0;
foreach my $line (<DATA>) {
    $line =~ s/^s+//; #remove leading spaces
    $line =~ s/s+$//; #remove trailing spaces
    $in_block = 1 if ($line =~ m/$begin_pattern/);
    $in_block = 0 if ($line =~ m/$end_pattern/);
    print "$linen" if ($in_block);
}
__DATA__
 something for storing 0
No. of blocks : 0
         Filt  Nothing                  Nothing
     Fac           Y    0    Mix    0      Mix   Mix  0                  Begin-to-search
96   Fac           Y    0    60     0      900   60   0                  0                   0
806  Fac           Y    0    0      0      0     0    0                  0                   0  
     Fac A|B|C|D   Y    11   0      0      0     0    0
340  Fac A|B|C|D   Y    11   0      0      0     0    0                  0                   0
     Mix M         Y    11   Mix    Mix    0     Mix  0                  End-to-search
573  Wrn A|B|C|D   Y    11   0      0      0     0    0                  0                   0
Mix M         Y    11   60     Mix    0     60   0                  ware

最新更新