我有一个如下所示的文件。
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
这里Begin
和Done
即将到来之前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
它的工作方式就是简单地准确地列出您想要的内容。您希望根据特定条件进行打印,因此我们在BEGIN
ning 时定义一个变量 ,p
它跟踪我们是否要打印。
^
当我们看到以 ( )开头的行时Update
,我们设置p
为0
,表示我们不想打印。- 然后我们
print
输入行当且仅当p
为真(即非零)时。 - 最后,当我们看到以 开头的行
Done
并且当前没有打印(也就是说, ifp
等于0
)时,我们设置p
为再次开始打印。
这里的主要区别在于打印仅完成后我们已经确定是否要继续打印,但在我们查看是否要在下一行恢复打印之前。