0

我有一个格式如下的文件:

Preamble

---------------------
Section 1
...
---------------------

---------------------
Section 2
...
---------------------

---------------------
Section 3
...
---------------------

Afterwords

我想通过分隔符提取每个部分,以便得到以下结果:

文件 0:

Section 1
...

文件1:

Section 2
...

文件2:

Section 3
...

...

有没有一种简单的方法可以做到这一点?谢谢。

4

4 回答 4

2

[更新] 使用 chomp 并$_使其更短。

这应该这样做:

如果您的输入记录分隔符是 21 的序列-,这很容易perl -ne

perl -ne 'BEGIN{ $/=("-"x21)."\n"; $i=0; } 
  do { open F, ">file".($i++); 
       chomp;
       print F; 
       close F; 
  } if /^Section/' yourfile.txt

应该工作,并创建文件file0......fileN

解释

也许更容易解释为独立的 Perl 脚本?

$/=("-"x21)."\n"; # Set the input-record-separator to "-" x 21 times
my $i = 0;        # output file number

open IN, "<yourfile.txt" or die "$!";

while (<IN>) {  # Each "record" will be available as $_ 
  do { open F, ">file".($i++); 
       chomp;     # remove the trailing "---..."
       print F;   # write the record to the file
       close F;   #
  } if /^Section/  # do all this only it this is a Section
}

Perl 的awk血统在这里很有用,所以让我们展示一个awk版本进行比较:

awk 'BEGIN{RS="\n-+\n";i=0} 
  /Section/ {chomp; print > "file_"(i++)".txt" 
}' yourfile.txt

与版本相比还不错perl,它实际上更短。$/Perl 中的变量RSawk. awk 在这里占了上风:RS可能是正则表达式!

于 2012-12-13T09:14:27.730 回答
1

您也可以使用 shell:

#!/bin/bash

i=0
while read line ; do

 #If the line contain "Section " followed by a 
 #digit the next lines have to be printed
 echo "$line"|egrep -q "Section [0-9]+"
 if [ $? -eq 0 ] ; then
  toprint=true
  i=$(($i + 1))
  touch file$i
 fi

 #If the line contain "--------------------"  
 #the next lines doesn't have to be printed
 echo "$line"|egrep -q "[-]{20}"
 if [ $? -eq 0 ] ; then
  toprint=false
 fi

 #Print the line if needed
 if $toprint ; then
  echo $line >> file$i
 fi

done < sections.txt
于 2012-12-13T09:36:51.147 回答
1

这是您要查找的内容:

awk '/^-{21}$/ { f++; next } f%2!=0 { print > "file" (f-1)/2 ".txt" }' file

结果:

内容file0.txt

Section 1
...

内容file1.txt

Section 2
...

内容file2.txt

Section 3
...

如您所见,上述文件名是“零”索引的。如果您希望将文件名“一个”编入索引,只需更改(f-1)/2(f+1)/2. HTH。

于 2012-12-13T16:02:38.450 回答
0

鉴于您的文件格式,这里有一个选项:

use strict;
use warnings;

my $fh;
my $sep = '-' x 21;

while (<>) {
    if (/^Section\s+(\d+)/) {
        open $fh, '>', 'file' . ( $1 - 1 ) . '.txt' or die $!;
    }

    print $fh $_ if defined $fh and !/^$sep/;
}

在您的数据上,创建file0.txt .. file2.txt包含file0.txt

Section 1
...
于 2012-12-13T15:23:44.793 回答