选择性删除两个模式之间的线条

选择性删除两个模式之间的线条

我有一个包含以下内容的文件,

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,则将变量设置f为零。

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

    如果该行包含Activitytask,则设置f1

    请注意,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 仅在非零时打印该行该行至少包含一个字符(任何类型)。

答案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

请注意 的使用//,这意味着之前使用的正则表达式:)

相关内容