パターン1に最も近い一致からパターン2より前のすべての行を印刷します。

パターン1に最も近い一致からパターン2より前のすべての行を印刷します。

この質問は以前に要求されたと確信していますが、正確なトリックを見つけることができません。

私の入力は次のとおりです。

Compiling File1
... commands ...

Compiling File2
... commands ...

Compiling File3
... commands ...
In file included from ...
In file included from ...
In file included from ...
error: could not find A

Compiling File4
... commands ...

Compiling File5
... commands ...
In file included from ...
In file included from ...
In file included from ...
error: could not find B

予想出力:

Compiling File3
... commands ...
In file included from ...
In file included from ...
In file included from ...
error: could not find A
---separator---
Compiling File5
... commands ...
In file included from ...
In file included from ...
In file included from ...
error: could not find B
---separator---

error:最も近い前の一致からCompiling現在の行、つまりエラーメッセージまで、各一致の全体的なコンテキストを印刷するシェルコマンドが必要です。正常にコンパイルされた他のすべてのファイルはスキップできます。

私は最後の一致が「コンパイル」されてから、すべてのテキストを含むパターンスペースを維持することで、awkまたはsedを使用してこれを簡単に達成できると思いますが、エラーなしで何千もの行がある可能性があります。非常に非効率的でしょうか?

ベストアンサー1

関連して、keeping a pattern space comprising all text since the last match "Compiling", but there can be thousands of lines without an error. Would it be very inefficient?印刷を開始する前に、一致する区切り記号のペアを識別するために入力ファイルを2回通過するなど、他の選択肢よりも効率が悪く、入力がファイルに保存されているかどうかに関係なく動作するという利点がある。パイプ。

次の機能を備えたシステムを使用する場合、最も効率的なアプローチは、次の間に呼び出しで2を使用することですtacawktac

$ tac file |
    awk '/^error:/{f=1; print "---separator---"} f; /^Compiling/{f=0}' |
        tac
Compiling File3
... commands ...
In file included from ...
In file included from ...
In file included from ...
error: could not find A
---separator---
Compiling File5
... commands ...
In file included from ...
In file included from ...
In file included from ...
error: could not find B
---separator---

それ以外の場合は、すべてのUnixシステムのすべてのシェルでawkを使用してください。

$ awk '
    /^Compiling/ { buf="" }
    { buf = buf $0 "\n" }
    /^error:/ { print buf "---separator---" }
' file
Compiling File3
... commands ...
In file included from ...
In file included from ...
In file included from ...
error: could not find A
---separator---
Compiling File5
... commands ...
In file included from ...
In file included from ...
In file included from ...
error: could not find B
---separator---

または、複数文字のRSとRTにGNU awkを使用します。

$ awk -v RS='\nerror:[^\n]+' -v ORS='\n---separator---\n' '
    sub(/(^|.*\n)Compiling/,"Compiling") { print $0 RT }
' file
Compiling File3
... commands ...
In file included from ...
In file included from ...
In file included from ...
error: could not find A
---separator---
Compiling File5
... commands ...
In file included from ...
In file included from ...
In file included from ...
error: could not find B
---separator---

おすすめ記事