关于AWK多行识别的问题

时间:2019-04-28 06:23:05

标签: awk

我刚刚读过Can awk patterns match multiple lines?,其接受的解决方案是在first half之后打印行的脚本。

how
second half #1
now
first half
second half #2
brown
second half #3
cow
/second half/ {
  if(lastLine == "first half") {
    print
  }
}

{ lastLine = $0 }

这给出了second half #2

不能理解为什么{ lastLine = $0 }必须走在之后 /second half/ {...}/。我尝试互换它们,却一无所获。

{ lastLine = $0 }

/second half/ {
  if(lastLine == "first half") {
    print
  }
}

我尝试阅读man awk,但没有涵盖了状态机。搜索“ awk状态机”只会给出链接的SO问题。

1 个答案:

答案 0 :(得分:0)

这由@oguzismail的评论回答。为了从未答复的队列中清除此问题,我将其扩展为一个答案。

AWK处理文本按记录。默认情况下,记录分隔符(RS)是换行符\n,因此AWK将每一行都视为一条记录。

在第一个(正确的)AWK脚本中,当处理第一个记录how时,匹配项/second half/位于

/second half/ {
  if(lastLine == "first half") {
    print
  }
}

评估为 false ,并且{ lastLine = $0 }将当前记录$0(即how)保存到变量lastLine

然后第二条记录second half #1到来,并且它与/second half/匹配,因此块{if (lastLine == "first half"){...}}的执行以lastLine作为前一条记录(how) ,即使$0second half #1

随着过程的进行,记录second half #2最终将通过嵌套块{}以便被打印。

如果我颠倒了AWK脚本中的两个动作,lastLine将始终保存当前记录$0,而/second half/在且仅当$0包含{ {1}},等于second half。因此,first half被第二个 nd AWK脚本$0授予不可能