从文件中提取两个模式之间的行

10

我需要从一个巨大的文件中提取在两个匹配模式之间的特定行。

假设pattern1(文件中唯一的)匹配特定的第n行pattern2(文件中不唯一的)匹配第n行后面的下一个匹配的第m行。那么我想提取并包括从第n行到第m行的所有行。

示例文件内容

***************************************************************************
text line # n-2
text line # n-1
********************************* Results *********************************
SUCCEEDED
...
...
some text
***************************************************************************
text line # m+1
text line # m+2
***************************************************************************

期望输出

********************************* Results *********************************
SUCCEEDED
...
...
some text
***************************************************************************

如果您能帮助我解决这个问题,将不胜感激。


我将此问题标记为重复,以覆盖所有情况。这样,我们就有了一个主要的地方,可以提供关于这个主题的良好解释。 - fedorqui
3个回答

24

这可以是一种方法:

$ awk '/pattern1/ {p=1}; p; /pattern2/ {p=0}' file
********************************* Results *********************************
SUCCEEDED
...
...
some text
***************************************************************************
  • 当找到pattern1时,将变量p设置为1。
  • 只有当p==1时才会打印行。这是通过条件p实现的。如果为真,则执行默认的awk操作,即print $0。否则,不执行。
  • 当找到pattern2时,将变量p设置为0。由于该条件在p条件之后被检查,因此它会打印第一次出现pattern2的行。

如果要精确匹配行:

$ awk '$0=="pattern1" {p=1}; p; $0=="pattern2" {p=0}' file

测试

$ cat a
***************************************************************************
text line # n-2
pattern1
********************************* Results *********************************
SUCCEEDED
...
...
some text
***************************************************************************
pattern2
text line # m+2
pattern2
***************************************************************************
$ awk '/pattern1/ {p=1}; p; /pattern2/ {p=0}' a
pattern1
********************************* Results *********************************
SUCCEEDED
...
...
some text
***************************************************************************
pattern2

谢谢您的回复。但是我无法匹配第n-1行和第m+1行。它们不是确定性的。 - jkshah
@jkshah 哦,现在我明白了。请检查我的更新答案。我考虑到了您正在寻找pattern1这一事实,请看测试。 - fedorqui
更新后的答案不包括第n和第m行,这是不需要的。您能否检查一下?它似乎与@Jotne建议的解决方案一致,并且可以正常工作。 - jkshah
好的,我对于打印 nn+1 的事情有些混淆了。现在我调整了条件以便打印两行:一行是具有 pattern1 的,另一行则是第一个具有 pattern2 的。希望现在清晰了 :) - fedorqui
1
现在这非常完美和简洁。非常感谢! - jkshah
显示剩余2条评论

8

使用 sed 命令:

$ sed '/start_pattern_here/,/end_pattern_here/!d' inputfile

而在 OP 的具体情况中:
$ sed '/[*]* Results [*]*/,/^[*]*$/!d' inputfile
********************************* Results *********************************
SUCCEEDED
...
...
some text
***************************************************************************

假设唯一的模式是*** Results ***,而非唯一的模式是********

谢谢您的回复。这个很好地运作了。 - jkshah
@devnull,您认为这个解决方案比awk解决方案更优吗?如果是,能否解释一下原因? - einpoklum

1
使用 awk
awk '/Result/ {p=1;print;next}  /^\*\*\*\*\*/ && p {p=0;print} p' file
********************************* Results *********************************
SUCCEEDED
...
...
some text
***************************************************************************

感谢您的回复。这个很好地运作了。 - jkshah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接