2

从一个unix脚本中,我想在一个文本文件中搜索一个字符串,然后返回模式之后的所有行,直到包含单词“Failed”的行。

例如,

Test Case Name "Blah"
Error 1
Error 2
Error 3
Failed
Test Case Name "Foo"
Pass
Test Case Name "Red"
Pass

在上面,我想搜索“Blah”,然后返回:

Error 1
Error 2
Error 3

直到“失败”行。“Blah”和“Failed”之间可以有任意数量的“Error”行。

任何使用 sed、awk 等的解决方案都是可以接受的。

谢谢!

4

2 回答 2

8

这是 awk 版本:

$ awk '/Failed/{p=0}p;/Blah/{p=1}' file
Error 1
Error 2
Error 3

如果你不介意打印边界线,你可以这样做

awk '/Blah/,/Failed/' file

一些解释这是如何工作的:awk 脚本本质上是一系列具有结构的块filter{actions},其中过滤器定义了哪些输入记录将应用操作。

所以第一个块/Failed/{p=0}说如果我们找到包含正则表达式的记录Failed,我们将变量p设置为零。

第二个块p;使用默认操作,即打印当前记录。因此,对于读取的每条记录,脚本都会检查p变量的值,并打印记录是否p具有非零值(相当于真实条件)。

第三个块/Blah/{p=1}说,如果我们找到一条包含正则表达式的记录,Blah将变量设置p为 1。

因此,如果我们将它们放在一起,脚本会开始读取所有输入行而不打印它们(因为 的初始值p为零)。找到一条记录包含后Blah,打印后面的记录,直到Failed找到一条记录包含。由于按照每个记录出现的顺序检查块,因此三个块的顺序将决定边界记录会发生什么。例如,如果要打印边界线,我们可以将脚本编写为awk '/Blah/{p=1}p;/Failed/{p=0}' file.

第二个命令awk '/Blah/,/Failed/' file使用范围结构(逗号)。范围构造的操作在这里很好地记录了:https ://www.gnu.org/software/gawk/manual/html_node/Ranges.html

于 2013-09-16T19:11:09.600 回答
3

这可能对您有用:

sed -n '/Blah/,/Failed/{//!p}' file
于 2013-09-16T20:01:43.720 回答