在两个匹配模式之间打印文件的行

Vin*_*nce 33 grep sed awk

如何打印两行之间的所有行,从第一行的一个模式开始,最后一行的另一个模式结束?


更新
我想提到这个文档是 HTML 是错误的。我似乎触动了神经,所以忘记了。除了打印文本文档的一部分之外,我并没有尝试解析 HTML 或使用它做任何事情。


考虑这个例子:

aaa
bbb
pattern1
aaa pattern2
bbb
ccc
pattern2
ddd
eee
pattern1
fff
ggg
Run Code Online (Sandbox Code Playgroud)

现在,我想打印的第一个实例之间的一切pattern1开始在一行的开头,并pattern2在另一条线的起点开始。我想在我的输出中包含pattern1pattern2行,但我不想要该pattern2行之后的任何内容。

pattern2可在该部分的其中一行中找到。我不想就此打住,但这很容易通过用^.

pattern1出现在 之后的另一行pattern2,但我根本不想看。我只是在寻找 的第一个实例pattern1和 的第一个实例之间的所有内容pattern2,包括在内。

我发现了一些几乎可以让我到达那里的东西sed

sed -n '/^pattern1/,/^pattern2/p' inputfile.txt
Run Code Online (Sandbox Code Playgroud)

...但是在下一个实例再次开始打印 pattern1

我能想到的使用方法的grep -n ... | cut -f1 -d:两次拿到两个号,然后tailhead得到我想要的部分,但我希望有一个更清洁的方式。也许awk是完成这项任务的更好工具?

当我开始工作时,我希望把它绑成一个git钩子。我也不知道该怎么做,但我仍在阅读和搜索:)

谢谢你。

Fel*_*xJN 40

您可以使用sed退出模式sed '/pattern/q',因此您只需要匹配,然后在第二个模式匹配时退出:

sed -n '/^pattern1/,/^pattern2/{p;/^pattern2/q}'
Run Code Online (Sandbox Code Playgroud)

这样只会显示第一个块。即使用一个子命令确保的^pattern2可引起sed后,才匹配退出^pattern1。两个^pattern2匹配项可以合并:

sed -n '/^pattern1/,${p;/^pattern2/q}'
Run Code Online (Sandbox Code Playgroud)

  • 第二个模式应该在子命令中,a la `sed -n '/A/,/B/{p;/B/q}'`。否则,如果 `/B/` 在 `/A/` 之前匹配,`sed` 将在打印任何内容之前退出。此外,可以像这样避免重复第二个模式:`sed -n '/A/,${p;/B/q}'`。 (8认同)
  • 如果pattern1和pattern2相同,有没有办法让这个工作正常? (3认同)

Wil*_*ill 18

作为一般方法,使用sed,可以轻松地将行从一个匹配打印到另一个匹配:

$ seq 1 100 > test
$ sed -n '/^12$/,/^15$/p' test
12
13
14
15
Run Code Online (Sandbox Code Playgroud)

使用 awk,你可以做同样的事情:

$ awk '/^12$/{flag=1}/^15$/{print;flag=0}flag' test
12
13
14
15
Run Code Online (Sandbox Code Playgroud)

您可以像这样使这些非包容性:

$ awk '/^12$/{flag=1;next}/^15$/{flag=0}flag' test
13
14

$ sed -n '/^12$/,/^15$/p' test | sed '1d;$d'
13
14
Run Code Online (Sandbox Code Playgroud)