特定のパターンの最後の発生から別のパターンの最初の発生まで印刷します。

特定のパターンの最後の発生から別のパターンの最初の発生まで印刷します。

おはようございます。質問によく似ています。最後のパターン発生から別のパターンへのGrep(数ヶ月前)詳細を追加しながら。

私は複数の繰り返しパターンがあり、その後に私が見つけたいパターンがあるファイルのUNIXスクリプトを書こうとしています。ただし、「tac」または「tail -r」(UNIXエミュレータMKS Toolkitを使用)がなく、Pattern2より前に最後に発生したPattern1を返し、Pattern1とPattern2の間のデータを返し、もう一度Pattern2を返そうとします。この例のパターンは「条件1」と「条件2」である。

出力:

...
Condition 1: A
data1
Condition 1: B
data2
Condition 2: C
data3
Condition 1: D
data4
Condition 1: E
data5
Condition 2: F
...

返すawk(またはsedですが、awkが正しいツールだと思う)スクリプトを作成したいと思います。

Condition 1: B
data2
Condition 2: C
Condition 1: E
data5
Condition 2: F

私はこれが次の行のどんな形だと思いますが、構文を正しく取得できません。

awk '/Condition 1/ {acc = $0;} /,/Condition 2/ {print ?}' output.out

「/,/」を使うのが難しいようです。誰でも提案があれば大変感謝します。この問題に関連する助けと時間をいただきありがとうございます。

答え1

努力する:

$ awk 'f{a=a"\n"$0} /Condition 1/{a=$0; f=1} f && /Condition 2/{print a; f=0}' output.out 
Condition 1: B
data2
Condition 2: C
Condition 1: E
data5
Condition 2: F

どのように動作しますか?

  • f{a=a"\n"$0}

    変数がftrue(0ではない)の場合、現在の行は変数の末尾に追加されますa

  • /Condition 1/{a=$0; f=1}

    現在の行にが含まれている場合は、現在の行にCondition 1設定し、変数を1に設定します。sf

  • f && /Condition 2/{print a; f=0}

    ftrueで、現在の行にが含まれている場合、Condition 2変数は印刷され、再び0にa設定されます。f

答え2

テキスト処理でリバースアドレッシングが必要な場合は、次のようにします。ex

それPOSIXの指定vi、これは(およびviその直前の)スクリプト可能な形式で非常に柔軟です。

printf '%s\n' 'g/Condition 2/?Condition 1?,.p' | ex output.out

これは次のことを意味します。

「condition2」パターンに一致する各行(グローバル)に対して、g「condition1」の前のインスタンスを後ろに検索し、その行から現在の行(「condition2」がある行など)までのすべての行をp印刷します。.

提供される入力の出力は説明とまったく同じです。

答え3

sed 'H;/PATTERN_1/h;/PATTERN_2/!d;x' infile

PATTERN_2これは、一致する行の前に少なくとも1つの一致する行があると仮定しますPATTERN_1。より一般的な場合は、PATTERN_1印刷する前にパターンスペースに存在するかどうかをテストする別の条件を追加します。

sed 'H;/PATTERN_1/h;/PATTERN_2/!d;x;/PATTERN_1/!d' infile

答え4

これはPerlの悪い点の一つです。

perl -0777 -ne '
    my $c1 = qr/Condition 1/;
    my $c2 = qr/Condition 2/;
    print for map {s/$c2.*?\n\K.*//s; $_}
              grep {/$c2/}
              split /(?=$c1)/ms;
' output.out

それ:

  • 完全なファイルの読み取り(-0777および-nオプションを使用)
  • 分割条件1が発生するところ(split)、
  • grep条件 2( ) に現れない段落をフィルタリングし、
  • 次に、関心のある各段落から条件付き2行()の後のmapすべての行を削除します。

関連情報