从标准输出中删除除上面匹配之外的匹配之前的行

从标准输出中删除除上面匹配之外的匹配之前的行

希望使用任何命令来产生以下结果。为了更加清晰而进行了编辑。我正在尝试删除 ^xyz 之前不是一行的所有 ^abc。

标准输出:

abc def
abc ghi
abc jkl
xyz mno
xyz pqr
abc def
abc ghi
abc jkl
xyz mno
xyz pqr

期望的结果:

abc jkl
xyz mno
xyz pqr
abc jkl
xyz mno
xyz pqr

答案1

您可以维护一个两行缓冲区(使用循环N D)并在删除它之前打印第一行(仅当xyz缓冲区中有 a 时):

$ cat stdout | sed ':a; $!N; /xyz/P; D; ba'
abc jkl
xyz mno
xyz pqr
abc jkl
xyz mno
xyz pqr

答案2

这是一句awk单行话。

awk '/^abc/ {prev = $0; prevabc = "true"}; /^xyz/ {if (prevabc == "true") {print prev; prevabc = "false" } ; print}' file.txt

解释

  • /^abc/ {prev = $0; prevabc = "true"};:如果该行以 开头abc,则不打印它,而是将该行的值存储在变量 中,并通过存储在变量 中prev来指示该行以 开头。abctrueprevabc
  • /^xyz/ {if (prevabc == "true") {print prev; prevabc = "false" } ; print}:如果该行以 开头xyz,则执行以下操作。
    • if (prevabc == "true") {print prev; prevabc = "false" }:如果上一行以abc(because prevabc == "true") 开头,则打印上一行prev并重置prevabcfalse
    • print:既然这一行以 开头xyz,那么也打印这一行。

相关内容