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>

などなど。

常に同じ数のカテゴリがあり、それらは常に同じ名前を持っていますが、その後に続く情報は異なります。カテゴリよりも情報が少ない場合があり、情報にはさまざまな内容が含まれます。

情報だけのものをキャプチャしたいので、当初の考えでは、 と の間Category3でキャプチャするように設定することでしたFile。ただし、これは機能していません。おそらく、私には明らかではない明確な理由があります。

これが私が使っているものです

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

私が提供したコードは、ファイル全体ではなく、これらの 2 つの単語を含む行のみを検索し、その間にあるものをキャプチャするためだ@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

あまりにも多くの人が、線をスキャンするという観点から、線がスキャンしたいレコードの1種類にすぎない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それ自身の「記録」になりますが、とにかく、それはあなたを少し近づけます。

于 2012-07-11T16:24:01.043 に答える
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 に答える
0

何が必要なのかを正確に伝えるのは非常に難しいですが、おそらくすべてのCategory情報なしで入力ファイルを印刷することでしょうか?

この 1 行の 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 に答える
-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 に答える