Perl 通过将两个模式之间的行写入新文件,将文件拆分为多个文件

Perl 通过将两个模式之间的行写入新文件,将文件拆分为多个文件,perl,Perl,这是输入文件: #cat myfile -- START whatever whatever -- END -- START whatever whatever -- END -- START whatever whatever -- END -- START whatever whatever -- END 我需要抓取--START和--END之间的行,并将这些行写入一个单独的文件。所以在这个用例中,我应该创建4个文件,如下所示: # cat file1 whatever whatev

这是输入文件:

#cat myfile
-- START
whatever
whatever
-- END

-- START
whatever
whatever
-- END

-- START
whatever
whatever
-- END

-- START
whatever
whatever
-- END
我需要抓取
--START
--END
之间的行,并将这些行写入一个单独的文件。所以在这个用例中,我应该创建4个文件,如下所示:

# cat file1
whatever
whatever

# cat file2
whatever
whatever

# cat file3
whatever
whatever

# cat file4
whatever
whatever
这是我的密码:

#!/usr/bin/perl
use strict;
use warnings;

open (my $fh, "<", "/var/tmp/myfile");
my $counter = 0;

while (<$fh>)
{
    if (/START/../END/)
    {
        my $filename = "/var/tmp/file".$counter;
        open (my $oh, ">", $filename);
        print $oh $_;
    }
    $counter++;
}
#/usr/bin/perl
严格使用;
使用警告;
打开(我的$fh,“,$filename);
打印$oh$;
}
$counter++;
}
问题:我的代码正在为
--START
--END


你能帮我弄清楚如何修复这个代码吗。谢谢。

不要为每一行打开新文件,它应该在每个范围的开头打开

使用范围的返回值确定文件应在何时打开,并仅打印边界条件之间的行

my $oh;
while (<$fh>) {
    if ( my $range = /START/ .. /END/ ) {
        # Start of Range - Open the file handle
        if ( $range == 1 ) {
            my $filename = "/var/tmp/file" . $counter++;
            open( $oh, ">", $filename ) or die $!;

        # Print until End of Range
        } elsif ( $range !~ /E/ ) {
            print $oh $_;
        }
    }
}
我的$oh;
而(){
如果(我的$range=/START//END/){
#范围开始-打开文件句柄
如果($range==1){
my$filename=“/var/tmp/file”。$counter++;
打开($oh,“>”,$filename)或死亡$!;
#打印到范围结束
}elsif($range!~/E/){
打印$oh$;
}
}
}

您可以将输入分隔符设置为“-END”标记,以便以“-END”分隔的块读取文件。然后可以使用正则表达式捕获所需的信息。我已经注释掉了您的文件I/O行,并使用了本地数据,因此您可以运行代码来检查其工作情况:

#!/usr/bin/perl
use strict;
use warnings;
use feature ":5.10";
use Data::Dumper;

#open (my $fh, "<", "/var/tmp/myfile");
my $counter = 0;

$/ = "-- END";
# while (<$fh>)
while (<DATA>)
{   if (/START\s*(\S.+?)\s*-- END/ms)
    {
    #    my $filename = "/var/tmp/file".$counter;
    #    open (my $oh, ">", $filename);
    #    print $oh $1;
        say "file $counter\n$1";
        $counter++;
    }
}

__DATA__

-- START
whatever1
whatever2
-- END

-- START
whatever3
whatever4
-- END

-- START
whatever5
whatever6
-- END

-- START
whatever7
whatever8
-- END

请解释一下这个
/START\s*(\s.+?)\s*--END/ms
regex<代码>\s*=>0个或更多空白字符<代码>\S=>非空白字符
+?
=>将所有内容匹配到正则表达式的下一位<代码>\s*=>0个或更多空白字符<代码>--结束=>文本字符串。括号捕获的内容从“开始”之后的第一个非空白字符开始,一直到“-END”之前的空白字符。操作符
ms
意味着将整个内容作为一行处理,并允许
匹配换行符。有关perl正则表达式的详细介绍,请参阅。感谢对正则表达式的解释+1.经过@miller的编辑,代码开始工作。谢谢+1.
file 0
whatever1
whatever2
file 1
whatever3
whatever4
file 2
whatever5
whatever6
file 3
whatever7
whatever8