ファイル内の3単語パターンをgrepまたは検索して、2番目と3番目の単語パターンの間の内容と一緒に印刷する方法

ファイル内の3単語パターンをgrepまたは検索して、2番目と3番目の単語パターンの間の内容と一緒に印刷する方法

PATTERN1とPATTERN2という単語を検索または検索し、後で印刷する方法PATTERN3を検索して検索PATTERN2 / PATTERN3の間に内容全体または一部を印刷したいです。 (Pattern1/2/3はファイルに複数回表示されます。)

入力ファイル

other lines
...
####Pattern 1####
...
other lines
...
####Pattern 2####
line 1
line 2
line 3
line 4
line 5
line ...
####Pattern 3####
...
other lines
####Pattern 1####
...
other lines
####Pattern 2####
line 1
line 2
line 3
line 4
####Pattern 3####
...
other lines

lを出力するために必要なものは次のとおりです。

####Pattern 1####
####Pattern 2####
line 1
line 2
line 3
line 4...etc
####Pattern 3####

ベストアンサー1

予想される順序に従わない可能性のあるすべての偽パターンをスキップする必要があることを指定したので、有限状態機械などのより複雑なものが必要です。

奇妙な場合と説明の両方を含むより複雑な入力ファイルの例は次のとおりです。

a
#### Pattern 2 #### Ignore because we have not yet seen Pattern 1
z
#### Pattern 3 #### Ignore because we have not yet seen Pattern 1, 2
b
#### Pattern 1 #### (!!)
#### Pattern 1 #### Don't print 1 in between 1-2
c
d
#### Pattern 2 #### (!!)
e
#### Pattern 1 #### Don't print 1 in between 2-3
#### Pattern 2 #### ?? Don't print 2 in between 2-3 ??
f
#### Pattern 3 #### (!!)
?? Now reset and accept look for the start of a NEW 1,2,3 cycle. Right ??
g
#### Pattern 3 #### Ignore
#### Pattern 2 #### Ignore
#### Pattern 3 #### Ignore
h
#### Pattern 1 #### (!!)
i
#### Pattern 3 #### Don't print 3 in between 1-2
j
#### Pattern 2 #### (!!)
k
l
#### Pattern 3 #### (!!)
m
n

予想出力:

#### Pattern 1 #### (!!)
#### Pattern 2 #### (!!)
e
f
#### Pattern 3 #### (!!)
#### Pattern 1 #### (!!)
#### Pattern 2 #### (!!)
k
l
#### Pattern 3 #### (!!)

したがって、3つの状態を持つ有限状態マシンを構築する必要があるようです。今、私たちは完全なスクリプトを書いています...

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

## Linear state machine 0 --> 1 --> 2 --> 0
my @patterns = (
    qr(Pattern 1),  # state 0: noprint;              match this: noprint && state = 1
    qr(Pattern 2),  # state 1: noprint;              match this:   print && state = 2
    qr(Pattern 3)   # state 2: print (NOT patterns); match this: print   && stage = 0
    );
my $state = 0;

while (<>) {
    if (0 == $state) {
        if (m/$patterns[0]/) {
            ++$state;
        }
    } elsif (1 == $state) {
        if (m/$patterns[1]/) {
            print;
            ++$state;
        }
    } elsif (2 == $state) {
        if (m/$patterns[0]/ || m/$patterns[1]/) {
            # Ignore
        } elsif (m/$patterns[2]/) {
            print;
            $state = 0;
        } else {
            print;
        }
    } else {
        die "Bad programmer! ($state)";
    }
}

少し醜いです。ハッシュは、より柔軟なステートマシンを実装するために使用できます。 [$state_num, $pattern_num] => sub { ...action... } ここでは、スキップ/無視がハッシュに表示されないすべての[ステータス、モード]の組み合わせに対するデフォルトの動作です。しかし、これは情熱的な読者のための練習として残されます;-)

おすすめ記事