0

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

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>

等等。

总有相同数量的类别并且它们总是具有相同的名称,但是它们后面的信息不同。信息可能比类别少,并且信息将包含不同的东西。

我想捕获只是信息的东西,所以我最初的想法是将它设置为在Category3and之间捕获File。但是,这不起作用,可能是出于某些对我来说并不明显的明确原因。

这是我正在使用的

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

4 回答 4

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开关(“multiline”),这个.字符仍然意味着除了换行符之外的任何东西。
  • 由于我们匹配回车,我们应该将所有内容都保留在记录中。虽然我们可能不想要"\n\n"最后。

诚然,这种方法使它File: filename成为自己的“记录”,但无论如何它会让你更接近一点。

于 2012-07-11T16:24:01.043 回答
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>
于 2012-07-11T17:48:19.563 回答
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
于 2012-07-11T18:10:33.133 回答
-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";
  }
}
于 2012-07-11T16:20:11.247 回答