使用 sed 捕获进程输出,捕获文本块然后在其中进行过滤

使用 sed 捕获进程输出,捕获文本块然后在其中进行过滤

我想用 sed 过滤一些 stdout,但我不知道怎么做。stdout 示例如下:

.
.
.
Model a.             # This should be captured
.
.
.
Metrics results:     # This should be captured
==================== # This should be captured
metric 1             # This should be captured
metric 2             # This should be captured
metric 3             # This should be captured
==================== # This should be captured
.
.
.
Model b              # This should be captured
.
.
.
Metrics results:     # This should be captured
==================== # This should be captured
metric 1             # This should be captured
metric 2             # This should be captured
metric 3             # This should be captured
==================== # This should be captured
.
.
.

其中.表示包含任意随机字符的行。因此结果将是

Model a
Metrics results:
====================
metric 1
metric 2
metric 3
====================
Model b
Metrics results:
====================
metric 1
metric 2
metric 3
====================

我可以使用什么 sed 命令?也希望能够解释一下它是如何工作的,以便了解 sed。

答案1

在你需要的问题中sed,但是有在标签中。对于grep我来说,这种过滤似乎是更自然的选择。

grep -E '^Model |^[Mm]etrics? |^=+$'

在这里,我尝试创建一个紧凑的表达式,但请注意,它[Mm]etrics?不会过滤掉例如,Metric whatever并且^=+$将匹配包含单个的行=。因此,您可能更喜欢不太紧凑、限制性更强的表达式,如下所示:

grep -E '^Model |^Metrics results:$|^metric |^====================$'

Metrics results:我假设包含或 的行中没有尾随空格====================。由于# This should be captured您添加了这些,我无法判断这是否是一个好的假设。如果需要,请调整表达式(删除一个或两个$锚点可能是一种调整)。

使用 GNU 3.7 测试grep


所用语法的概述:

  • grep -Egrep模式解释为扩展正则表达式 (ERE)。grep不包含-E使用基本正则表达式 (BRE)。您的问题可以用 BRE 解决。我选择 ERE 是因为模式看起来更简单(即它们更易于阅读)。
  • foo|bar|baz匹配foobarbaz。这需要grep -E。如果没有-E它,则会是foo\|bar\|baz
  • ^表达式的开头是一个与行首匹配的锚点。
  • 类似地$,末尾匹配行的末尾。
  • [Mm]匹配Mm
  • s?匹配零个或一个s。这是必需的-E。如果没有-E它将是s\?1
  • =+匹配一个或多个=字符。这需要grep -E。如果没有,-E则为=\+1。或者可以使用==*for (=*匹配零个或多个=字符)。

第一个不带的命令-E

grep '^Model \|^[Mm]etrics\? \|^==*$'

1 \?\+不是 POSIX BRE 标准的一部分


cmmnd你可能知道这一点,但为了以防万一:你用以下方法过滤一些

cmmnd | grep …

相关内容