Regex 使用perl将输入文件拆分为多个文件

Regex 使用perl将输入文件拆分为多个文件,regex,perl,split,Regex,Perl,Split,我有一个格式如下的输入文件 Line 1 ...... Line 2 ...... Line 3 ...... Line 4 ...... run_diagnosis ./FAILCYCLE/pat.UMK004_W13_X3Y12.dat.trans -cycle_offset 1 -verbose Line 48 .... Line 49 .... Line 50 ..... run_diagnosis ./FAILCYCLE/pat.UMK004_W13_X13Y10.dat.trans

我有一个格式如下的输入文件

Line 1 ......
Line 2 ......
Line 3 ...... 
Line 4 ......
run_diagnosis ./FAILCYCLE/pat.UMK004_W13_X3Y12.dat.trans -cycle_offset 1 -verbose
Line 48 ....
Line 49 ....
Line 50 .....
run_diagnosis ./FAILCYCLE/pat.UMK004_W13_X13Y10.dat.trans -cycle_offset 1 -verbose 
Line 52 ..... 
Line 53 ..... 
Line 53 ..... 
run_diagnosis ./FAILCYCLE/pat.UMK004_W13_X15Y4.dat.trans -cycle_offset 1 -verbose
Line 55 .....
Line 56 ..... 
Line 57 .....
我搜索的关键字是“运行诊断”。
我想将内容拆分为多个文件(文件数量将等于输入文件中关键字“run_diagnosis”出现的数量)

第一次出现“run_diagnosis”以上的数据是无用的内容。 我希望输出像这样

文件1:

run Diagnosis ./FAILCYCLE/pat.UMK004_W13_X3Y12.dat.trans -cycle_offset 1 -verbose
Line 48 ....
Line 49 .... 
Line 50 ..... 
文件2:

run_diagnosis ./FAILCYCLE/pat.UMK004_W13_X13Y10.dat.trans -cycle_offset 1 -verbose 
Line 52 ..... 
Line 53 ..... 
Line 53 .....
依此类推…直到最后出现关键字“run_diagnosis”。
我尝试过使用数组,但它只能打印关键字的第一次和第三次出现,并跳过第二次和第四次出现

另外,要创建的文件名来自“运行诊断”行条目。
在我的例子中,文件1的名称将是:UMK004_13_3_12.ext传递的输入文件

my $file_in = 'Diagnosis_add_seal_ring.ppd';
my $ext = (fileparse($file_in,'\..*'))[2];
my $start_of = 'Unwanted_Content.txt';
my $line;
my @grabbed;

open my $IN, "<", $file_in or die "unable to open $file_in $!"; 
open my $OUT, ">", $start_of or die "unable to open $start_of file $!"; 

  while ($line = <$IN>) { 
      if ($line =~ /^run_diagnosis/) { 
         my $file_name = (split /\./, $line)[2] . $ext;
         push @grabbed, $line;
             while (<$IN>) {
                 last if /^run_diagnosis/;
                 push @grabbed, $_;
             }
         open $OUT, ">", $file_name or die "... $!"; 
         print $OUT @grabbed; 
         undef(@grabbed)
  }     
  close $OUT;
}
my$file\u in='diagnostics\u add\u seal\u ring.ppd';
my$ext=(fileparse($file_in,\..*)[2];
my$start_of='不需要的内容.txt';
我的美元线;
我的"抓",;
打开我的$IN,“,$start_of或die”无法打开文件$的$start_!“;
而($line=){
如果($line=~/^run\u diagnosis/){
我的$file\u name=(拆分/\。/,$line)[2]。$ext;
按@线;
而(){
最后一个if/^run_诊断/;
按@抓取,$\;
}
打开$OUT,“>”,$file\u name或die“…$!”;
打印$OUT@jacked;
未定义(@0)
}     
收尾美元;
}

你能给我介绍一下吗。

这个节目会按照你的要求做的。只要找到
run\u diagnosis
行,它就会打开一个新的输出文件

use strict;
use warnings;

my $file_in = 'Diagnosis_add_seal_ring.ppd';
open my $fh, '<', $file_in or die qq{Unable to open "$file_in" for input: $!};
my ($file_ext) = $file_in =~ /(\.[^.]*)\z/;

my $filenum;
my $fh_out;

while ( <$fh> ) {
  if ( /^run_diagnosis/ ) {
    my $file_out = (split /\./)[2] . $file_ext;
    warn $file_out, "\n";
    open $fh_out, '>', $file_out or die qq{Unable to open "$file_out" for output: $!};
    select $fh_out;
  }
  print if $fh_out;
}

您可以在读取输入时动态打开输出文件。每当遇到
^run_diagnosis
时,只需打开一个新的输出文件,并使用相同的文件句柄变量继续写入:

#!/usr/bin/perl

use strict;
use warnings;

my $file_in = 'Diagnosis_add_seal_ring.ppd';
my ($ext) = $file_in =~ /([^.]+)$/;

open my $IN, "<", $file_in or die "unable to open $file_in $!";
my $OUT;
my $file_num = 0;

while (<$IN>) {
    if (/^run_diagnosis[^.]+\.[^.]+\.([^.]+)/) {
        my $file_out = "$1.$ext";
        open $OUT, ">", $file_out or die "unable to open $file_out file $!";
        $file_num++;
    }
    print $OUT $_ if ($file_num);
}
#/usr/bin/perl
严格使用;
使用警告;
我的$file_in='Diagnosis_add_seal_ring.ppd';
我的($ext)=$file_in=~/([^.]+)$/;
打开我的$IN“,$file\U out或die“无法打开$file\U out file$!”;
$file_num++;
}
打印$OUT$\uIf($file\u num);
}
#/usr/bin/env perl
使用v5.20;
使用实验性qw/签名postderef/;
使用自动模具;
我的$i=0;
我的$fh;
while()
{
如果($\uu=~m/run\u diagnosis/)
{
$i++;
打开$fh、“>”、“文件”.“$i.“.txt”;
可写文件($\uFh,$fh);
}否则
{
除非($i==0)
{
打开$fh、“>>”、“文件”.“$i.“.txt”;
写入文件($\uFh,$fh)
}
}
}
子写入文件($line,$fh)
{
打印$fh$行;
收盘价$fh;
}

如果($line=~…){…将
my@grapped
移动到
if($line=~…){…
?运行诊断发生之间的行数是否始终相同?
unde@grapped
也会强制执行不必要的垃圾收集。您应该使用
@grapped=()
使用警告
优于命令行或shebang lineHi Borodin上的
-w
,…上述所有解决方案都非常有效。非常感谢您的帮助…将通读代码并理解
#!/usr/bin/perl

use strict;
use warnings;

my $file_in = 'Diagnosis_add_seal_ring.ppd';
my ($ext) = $file_in =~ /([^.]+)$/;

open my $IN, "<", $file_in or die "unable to open $file_in $!";
my $OUT;
my $file_num = 0;

while (<$IN>) {
    if (/^run_diagnosis[^.]+\.[^.]+\.([^.]+)/) {
        my $file_out = "$1.$ext";
        open $OUT, ">", $file_out or die "unable to open $file_out file $!";
        $file_num++;
    }
    print $OUT $_ if ($file_num);
}
#!/usr/bin/env perl

use v5.20;
use experimental qw/signatures postderef/;
use autodie;

my $i = 0;
my $fh;

while(<>)
{
    if($_ =~ m/run_diagnosis/)
    {
        $i++;
        open $fh, ">", "File_".$i.".txt";
        writeFile($_, $fh);
    }else
    {
        unless($i==0)
        {
            open $fh, ">>", "File_".$i.".txt";
            writeFile($_, $fh)
        }
    }
}

sub writeFile($line, $fh)
{
    print $fh $line;
    close $fh;
}