2

以下のようにフォーマットされたテキストファイルを解析しています

> alpha
apple
airplane
art
> beta
bear
blue
beat
> charlie
cow
cent
coat

alpha beta charlieモチーフ(「た」など)を持つエントリ( )を探しています。モチーフが見つかった場合は、各エントリの下にある単語を出力しようとしています ( bear blue beat)。したがって、この例では、次の出力が必要です

> beta
bear
blue
beat

エントリ行を印刷する方法はわかりましたが、その下の行を印刷する方法がわかりません。どんなアイデアでも大歓迎です。

my $motif = "ta";
my $file = "file.pl";
open(INPUT, $file) or die "Can't open file.\n";
parse($motif);

sub parse{
    my ($x) = (@_);
    while(<INPUT>){
        if($_ =~ />*($x)/){
            print $_."\n";
#       if($_ !~ />/){
#           print $_."\n";
        }else{
            next;
        }
    }
}
4

5 に答える 5

4

別のオプションは次のとおりです。

use strict;
use warnings;

my $motif = pop;
local $/ = '>';    # record separator

while (<>) {
    chomp;
    print $/ . $_ if /(?<=\x20).*?$motif/;
}

使用法:perl script.pl data.txt 'ta'

data.txtのデータに出力します。

> beta
bear
blue
beat

この表記local $/ = '>'は、レコード区切り文字を>通常のの代わりに設定する\nため、それぞれ>が読み取られるレコードの開始をマークします。検索する行の直後にスペースがあり>、それがポジティブルックビハインド(?<=\x20)が一致しようとするものです。

次の手順を実行して、出力をファイルにリダイレクトできますperl script.pl data.txt 'ta' >output.txt

于 2013-02-13T04:45:36.860 に答える
1

このタイプの問題は、Perl の範囲演算子 (このコンテキストでは、"フリップフロップ" 演算子としてより一般的に知られています) にとって自然なことのように思えます。ただし、要件の詳細により、予想よりも少し複雑になりました。

#!/usr/bin/env perl    

use strict;
use warnings;

parse('ta');

sub parse {
  my $pattern = shift;

  my $seq;
  while (<DATA>) {
    if ($seq = /^>.*$pattern/ ... (/^>/ && !/^>.*$pattern/)) {
      print unless $seq =~ /E0$/;
    }
  }
}


__DATA__
> alpha
apple
airplane
art
> beta
bear
blue
beat
> charlie
cow
cent
coat

出力:

> beta
bear
blue
beat
于 2013-02-13T10:51:43.567 に答える