Regex Perl-如何从文本文件中省略行?

Regex Perl-如何从文本文件中省略行?,regex,string,perl,Regex,String,Perl,我有一个文本文件,我希望省略文本文件中的一些行,并使用该字符串创建一个新文件。很好的一点是,我的文本文件以包含“START”和“END”的行开始我需要的文本块 例如,我的文本文件如下所示: 1 2 3 Start 4 5 6 End 7 8 Start 9 10 End 所需的输出将是两个字符串,我可以将它们输出到文本文件中,如下所示: Start 4 5 6 End 我目前拥有的: open(RH, '<', $fileName) or die $!; while(<RH&g

我有一个文本文件,我希望省略文本文件中的一些行,并使用该字符串创建一个新文件。很好的一点是,我的文本文件以包含“START”和“END”的行开始我需要的文本块

例如,我的文本文件如下所示:

1
2
3
Start
4
5
6
End
7
8
Start
9
10
End
所需的输出将是两个字符串,我可以将它们输出到文本文件中,如下所示:

Start
4
5
6
End
我目前拥有的:

open(RH, '<', $fileName) or die $!;

while(<RH>) {
    #print $_;
    chomp $_;
    if ($_ eq 'START') {
        $str = "$str"."$_\n";
    }
}

open(RH,您可以使用来自AWK的一些Perl传统,只需这样做(假设您的文件名为foo.txt)

表达式
/Start/./End/
的意思是“在匹配
/Start/
的第一行,直到匹配
/End/
的下一行”

awk的等效代码为

awk '/Start/,/End/ {print}' foo.txt
#将整个文件读入字符串“$str”:

打开我的$fh,“使用GNU
grep

grep -Poz '(?ms)^Start.*?^End\n' in_file
在这里,GNU使用以下选项:
-P
:使用Perl正则表达式。
-o
:仅打印匹配项(每行1个匹配项),而不是整行。
-z
:将输入和输出数据视为行序列,每个行以零字节(ASCII NUL字符)而不是换行符终止。因此,您可以匹配输入中的换行符

(?ms)
:分别启用
m
s
,以允许多行匹配,并允许
匹配换行符

另请参见:

使用
作为“触发器”操作符

# Switch to a lexical filehandle
# (as this is modern best practice)
open(my $rh, '<', $fileName) or die $!;

# Open an output filehandle
my $x = 1;
open my $out, '>', "$filename.out.$x" or die $!;

while(<$rh>) {
  print $out $_ if /Start/ .. /End/;

  # Open a new output file if we've seen 'End'
  if (/End/) {
    ++$x;
    open my $out, '>', "$filename.out.$x" or die $!;
  }
}
#切换到词法文件句柄
#(因为这是现代最佳实践)
打开(my$rh、“$filename.out.$x”或死亡$!;
while(){
打印$out$\if/Start//End/;
#如果我们看到“结束”,请打开一个新的输出文件
如果(/End/){
++$x;
打开我的$out,“>”、“$filename.out.$x”或die$!;
}
}

$/=undf;
undf$/;
好,而且
local$/;
是本地化后最好的。不确定这是否正常工作。我假设您的代码示例打印出了我想要的输出,但不幸的是没有打印到终端。在while循环之前,文本文件得到了正确加载d转换为$str,但while循环运行不正常。@NelsonSwasono-我不知道何时使用/m vs/s--请删除其中一个。不幸的是,这仍然不起作用,您的内存中没有/m或/ssample@NelsonSwasono-TIMTOWTDI--我喜欢说
=~m{…}
而不是
=~/…/
。这会导致
=~m{…}msg
而不是
=~/…/msg
。如果我想在我的perl脚本中使用这些行,我该如何使用它?@NelsonSwasono另一篇文章中回答了几乎相同的主题。我不确定你为什么在说“谢谢”后删除了该线程“通常,你会让它作为一个资源,为将来的访问者提供与你相同的问题。考虑对这个线程和你问的其他问题做同样的事情。
awk '/Start/,/End/ {print}' foo.txt
# Read the entire file into a string `$str`:
open my $fh, '<', 'file_name' or die "Can't open file $!";
my $str = do { local $/; <$fh> };
close $fh;

while ($str =~ m{\n(START\n.*\nEND)\n}msg) {
    # Do something with each START...END set of lines
    print "$str\n";
}
grep -Poz '(?ms)^Start.*?^End\n' in_file
# Switch to a lexical filehandle
# (as this is modern best practice)
open(my $rh, '<', $fileName) or die $!;

# Open an output filehandle
my $x = 1;
open my $out, '>', "$filename.out.$x" or die $!;

while(<$rh>) {
  print $out $_ if /Start/ .. /End/;

  # Open a new output file if we've seen 'End'
  if (/End/) {
    ++$x;
    open my $out, '>', "$filename.out.$x" or die $!;
  }
}