Perl捕获文件中的文本

时间:2012-07-11 16:08:53

标签: perl

好吧,所以我正在读一个看起来像的文件:

File: namehere

Category1<br>
Category2<br>
Category3<br>
Info1<br>
Info2<br>
Info3<br>

File: namehere

Category1<br>
Category2<br>
Category3<br>
Info1<br>
Info2<br>
Info3<br>

等等。

总是有相同数量的类别,它们总是具有相同的名称,但是它们之后的信息不同。信息可能少于类别,信息将包含不同的内容。

我想捕捉那些只是信息的东西,所以我最初的想法是将其设置为在Category3File之间捕获。然而,这不起作用,可能是出于一些明显的原因,这对我来说并不明显。

这是我正在使用的

if ( /Category1([\s\S]+?)File/ ) {
  push(@files, $1);
  print @files;

我没有为@files得到任何东西而我认为这是因为我提供的代码只搜索包含这两个单词的行并捕获它们之间的内容,而不是整个文件。任何帮助/建议?


修改

如果我正在阅读这样的内容,我该怎么改变呢?

File: namehere

Category1<br>
Category2<br>
Category3<br>
Info1<br>
Info2<br>
Info3<br>

Info1<br>
Info2<br>
Info3<br>

Info1<br>
Info2<br>

4 个答案:

答案 0 :(得分:0)

这看起来像是$RS的工作!

太多人发现很难从扫描线的角度切换到Perl透视图,其中行只是您可能想要扫描的一种记录。如果更改记录分隔符,您将获得更多逻辑记录。然后,您可以指定要扫描的模式,找出它停止的位置并记录其余的记录

use English qw<$RS>;
use English qw<@LAST_MATCH_END>;

local $RS = "\n\n"; 

while ( <$in> ) {
    next unless m/^Category3.*\n/m;
    push @data, substr( $_, $LAST_MATCH_END[0] );
}
  • 由于我们只使用m开关(“多行”),.字符仍然表示除换行符之外的任何内容。
  • 由于我们匹配回车,我们应该把所有内容留在记录中。虽然我们最后可能不想要"\n\n"

不可否认,这种方法使File: filename成为了自己的“记录”,但无论如何它会让你更接近。

答案 1 :(得分:0)

很难确切地说出你想要什么,但也许是在没有所有Category信息的情况下打印输入文件?

这个单行Perl程序将为您做到这一点

perl -ne "print unless /^Category/" myfile

<强>输出

File: namehere

Info1<br>
Info2<br>
Infor3<br>

File: namehere

Info1<br>
Info2<br>
Info3<br>

答案 2 :(得分:0)

我发现这样的任务必须是“快速的”:

示例文件:

$ cat a.txt
File: namehere

Category1
Category2
Category3
Info1
Info2
Infor3

File: namehere

Category1
Category2
Category3
Info1
Info2
Infor3

解决方案:

$ perl -le 'local $/= undef; $_ = <>; 
        @g = map {/^Category3$\s*(.*?)\s*\z/ms; $1} 
            grep{/Category3/} 
            split /^File:.*$/m; 
        print for @g' a.txt
Info1
Info2
Infor3
Info1
Info2
Infor3

答案 3 :(得分:-1)

#! /usr/bin/perl -w
use strict;

my %hoa;  # a hash of arrays: key = file name each array element is
          # the info1, info2 etc that is listed under the file name
my $key;

open(F, "$ARGV[0]");

while (<F>) {
  chomp;
  if (/File/) {
    my @line = split /:/;
    $key = $line[1];
  }

  if (/Info/) {
    push @{ $hoa{$key} }, $_;
  }
}

foreach my $k ( sort keys %hoa ) {
  my @list = @{ $hoa{$k} };
  foreach my $l (@list) {
    print $k, "\t", $l, "\n";
  }
}