2つのパターン間の線を選択的に削除する

2つのパターン間の線を選択的に削除する

以下の内容を含むファイルがあります。

Hello world Unix!!
Its bright world
Current time is HH:mm:ss
Next action plan is item #3
End of task.
Thank you.


Hello world Linux!!
All actions completed.
End of Activity.
Thanks.

キーワード「world」を含むすべての行と、特定のキーワード セット (例、「Activity」または「task」) を含む行が見つかるまで、後続のすべての行を選択的に削除したいと思います。

望ましい出力:

End of task.
Thank you.
End of Activity.
Thanks. 

答え1

試す:

$ awk  -v f=1 '/world/{f=0} /Activity|task/{f=1} f' File
End of task.
Thank you.


End of Activity.
Thanks.

使い方:

  1. -v f=1

    awk 変数を作成しf、 に設定します1

  2. /world/{f=0}

    現在の行に が含まれている場合world、変数をf0 に設定します。

  3. /Activity|task/{f=1}

    行にActivityまたは のいずれかが含まれている場合はtaskに設定しfます1

    world上記の部分とここは正規表現として扱われることに注意してください。また、大文字Activitytask小文字は区別されます。

  4. f

    がゼロ以外の場合はf、行を出力します。

空白行も削除するには

$ awk  -v f=1 '/world/{f=0} /Activity|task/{f=1} f && /./' File
End of task.
Thank you.
End of Activity.
Thanks.

f && /./fがゼロでない場合にのみ行を出力するようにawkに指示するそして行には少なくとも 1 つの文字 (任意の種類) が含まれます。

答え2

awkの解決策ほどきれいではありませんが、OPが質問にタグを付けたのでsed以下も同様です:

#with blank lines
sed '/world/,/task\|Activity/{//!d};/world/d' file

#without blank lines
sed '/world/,/task\|Activity/{//!d};/world\|^$/d' file

の使用に注意してください//。これは、以前に使用された正規表現を意味します :)

関連情報