テキスト処理 - 間に正確なテキストを含む2行を取得します。

テキスト処理 - 間に正確なテキストを含む2行を取得します。

私のファイルには、開始キーワード「Start」、終了キーワード「End」、およびその間のオプションのテキストを含む不明な数のテキストブロックが含まれており、各行に正しいキーワード「Disk」が含まれています。 「テキストブロックを削除する必要があります。それらの間には関係ありません。例を参照してください。

次のように入力を処理しています。

Server1:Start
Server1:End
Server2:Start
Disk1
Disk2
Server2:End
Server3:Start
Disk1
Server3:End

、私が望む出力は次のとおりです。

Server2:Start
Disk1
Disk2
Server2:End
Server3:Start
Disk1
Server3:End

「awk」または「sed」を使用して2行の間のテキストを見つけることができることを知っていますが、2行が複数回表示される場合、または2行の間にテキストがない場合はどうすればよいかわかりません。

Ubuntu 17.10を実行しています。

どんな助けでも待ちます。

編集:を使用してこれを行うことができると思ったので、最初に投稿を削除しましたが、これはsed -e '/Start/,/End/d'実際にすべてを削除しました。

答え1

Start連続した行と行を削除するには、EndGNU sedで次のことを行う必要があります。

$ sed -e '/Start/ {N; /^\(.*\):Start\n\1:End$/d }' < input

が表示されたら、Start次の行をロードNし、バッファーの内容が両方の行と同じであることを確認してください(Somename:Start\nSomename:End改行文字)。存在する場合は削除してください。ここでは、ペアの最初のグループへの参照であり、そこで見つかった同じ文字列と一致します。任意の文字()のうち任意の数字()のみを表します。Somename\n\1\(..\).**.

sed -e '/Start/,/End/d'範囲は開始パターンと終了パターンの間のすべての行と一致するため、を使用するとすべての行が削除されます。入力の内容はすべて間にあるため、StartすべてのEnd内容が削除されます。

答え2

私はこれらのタスクをawkで実行するのが好きなので、別のソリューションです。

BEGIN { 
    RS="End\n"
    ORS="End\n"
} 
NF > 2

組み込み変数RSまたはレコード区切り変数を使用して、awkはそれらの間の各項目をEnd\nレコードとして扱い、両方とも単一の単語であると仮定しservername:Startますservername:End。これは、lineを介して複数のフィールドを持つ行を印刷する場合にのみ当てはまりますNF > 2。これがtrueの場合、行全体が印刷され、End\n出力レコード区切り文字として使用されます(ORS)。

~$>echo '
Server1:Start
Server1:End
Server2:Start
Disk1
Disk2
Server2:End
Server3:Start
Disk1
Server3:End
' | awk 'BEGIN { RS="End\n"; ORS="End\n"; } NF > 2;'
Server2:Start
Disk1
Disk2
Server2:End
Server3:Start
Disk1
Server3:End

関連情報