2012-07-30 159 views
3

我有一个由数千篇文章组成的大文本文件,我试图将其分割为单独的文件 - 每篇文章对应于我希望保存为article_1,article_2等的每篇文章每篇文章都以包含单词/ DOCUMENTS /的行开头。 我对perl完全陌生,任何见解都会非常棒! (甚至在良好的doc网站上提供建议)。非常感谢。 到目前为止,我曾尝试样子:Perl将文本文件分割成块

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

my $id = 0; 
my $source = "2010_FTOL_GRbis.txt"; 
my $destination = "file$id.txt"; 

open IN, $source or die "can t read $source: $!\n"; 

while (<IN>) 
    { 
    { 
     open OUT, ">$destination" or die "can t write $destination: $!\n"; 
     if (/DOCUMENTS/) 
     { 
     close OUT ; 
     $id++; 
     } 
    } 
    } 
close IN; 
+2

我试着重新缩进你粘贴的东西,正确的,我看到一对多余的'{}'s。你确定你粘贴了整个东西吗?另外,下次在问题/答案中粘贴代码时,请使用“{}”按钮。 – ArjunShankar 2012-07-30 09:52:34

回答

2

你看过Programming Perl?这是开始的最好的书!

我不明白你在做什么。我假设你有文章,并有文章,并希望获得单独文件中的所有文章。

use warnings; 
use strict; 
use autodie qw(:all); 

my $id   = 0; 
my $source  = "2010_FTOL_GRbis.txt"; 
my $destination = "file$id.txt"; 

open my $IN, '<', $source; 
#open first file 
open my $OUT, '>', $destination; 

while (<$IN>) { 
    chomp; # kill \n at the end 
    if ($_ eq '/DOCUMENTS/') { # not sure, am i right here or what you looking for 
     close OUT; 
     $id++; 
     $destination = "file$id.txt"; 
     open my $OUT, '>', $destination; 
    } else { 
     print {$OUT} $_, "\n";  # print into file with $id name (as you open above) 
    } 
} 
close $IN; 
+0

你可以摆脱“我的$目的地”的第一项任务。另外我相信OP意味着字符串'/ DOCUMENTS /'(如文件系统中的一段路径)是新文章标题行的一部分,所以你应该说'if(m {/DOCUMENTS /}){'。 – simbabque 2012-07-30 11:19:37

+0

您正确的“DOCUMENT”是每篇文章的标题的一部分。但上面的脚本不起作用,循环不起作用我只是用我的所有文章里面的file0.txt。 – user1562471 2012-07-30 17:24:48

4

假设/DOCUMENTS/自动出现在一行。因此你可以使记录为分隔符。

use English  qw<$RS>; 
use File::Slurp qw<write_file>; 
my $id  = 0; 
my $source = "2010_FTOL_GRbis.txt"; 

{ local $RS = "\n/DOCUMENTS/\n"; 
    open my $in, $source or die "can t read $source: $!\n"; 
    while (<$in>) { 
     chomp; # removes the line "\n/DOCUMENTS/\n" 
     write_file('file' . (++$id) . '.txt', $_); 
    } 
    # being scoped by the surrounding brackets (my "local block"), 
    close $in; # an explicit close is not necessary 
} 

注:

  • use English声明全局变量$RS。这个“杂乱的名字”是$/。见perldoc perlvar
  • 行分隔符是默认记录分隔符。也就是说,文件读取的标准单位是记录。这只是,由默认,一个“线”。
  • 正如您在链接文档中发现的那样,$ RS只需要文字字符串。因此,使用这样的想法,即文章之间的划分是'/DOCUMENTS/'本身在一行上,我指定newline + '/DOCUMENTS/' + newline。如果这是发生在某行的某个路径的一部分,那么该特定值将不适用于记录分隔符。
+0

非常感谢您的回复。你能解释记录分隔符是如何工作的吗?我应该首先声明变量RS吗? – user1562471 2012-07-30 17:20:27

+0

@ user1562471,请参阅Notes部分,刚添加。 – Axeman 2012-07-30 18:23:02

+0

再次感谢。文档本身不会出现在一行上,而是表达式的一部分,例如“150个文档中的1个”,因此它不会用作记录分隔符。但我会尝试找到另一个分隔符,它是一个整行。 – user1562471 2012-07-30 19:52:41