awk - 从块中删除带有起始词和结束词的行

awk - 从块中删除带有起始词和结束词的行

我有一个如下所示的文件。

Line1
line2
Begin1
Select is running
Done1
Begin
Update is in progress
Done
Begin2
Select is running
Done2
Begin3
select is running
Done4
line last

我想找到单词 update 并删除从 begin (上一行)开始直到完成(下一行)的块

所以最终的输出将是

Line1
Line2
Begin1
Select is running
Done1
Begin2
Select is running
Done2
Begin3
select is running
Done4
line last

我使用以下代码来删除,但不幸的是,如果没有字符串 Being 和 Done,它会删除所有行。

awk -i inplace  '/BEGIN/ {f=1} f {s=s?s"\n"$0:$0;if ($0~/update/) f=s=0} /COMMIT/ && f {print s;f=s=0}' filename


Begin1
Select is running
Done1
Begin2
Select is running
Done2
Begin3
select is running
Done4

更新:

另一个用例:

如果另一个文件具有以下结构,

Line1
line2
Begin
Select is running
Done
Begin
Done
Update is in progress
Begin2
Select is running
Done2
Begin3
select is running
Done4
line last

这里BeginDone即将到来之前update。所以我想删除那三行。有什么推荐的方法来实现这一目标吗?

答案1

将此 awk 脚本保存到例如717212.awk

BEGIN { p=1 }
/^Update/ { p=0 }
p { print $0 }
p==0 && /^Done/ { p=1 }

然后这应该执行您对给定输入文件的请求inputfile

awk -f 717212.awk inputfile

它的工作方式就是简单地准确地列出您想要的内容。您希望根据特定条件进行打印,因此我们在BEGINning 时定义一个变量 ,p它跟踪我们是否要打印。

  • ^当我们看到以 ( )开头的行时Update,我们设置p0,表示我们不想打印。
  • 然后我们print输入行当且仅当p为真(即非零)时。
  • 最后,当我们看到以 开头的行Done并且当前没有打印(也就是说, ifp等于0)时,我们设置p为再次开始打印。

这里的主要区别在于打印仅完成我们已经确定是否要继续打印,但在我们查看是否要在下一行恢复打印之前。

相关内容