![打印两个匹配模式之间的文件行](https://linux22.com/image/84093/%E6%89%93%E5%8D%B0%E4%B8%A4%E4%B8%AA%E5%8C%B9%E9%85%8D%E6%A8%A1%E5%BC%8F%E4%B9%8B%E9%97%B4%E7%9A%84%E6%96%87%E4%BB%B6%E8%A1%8C.png)
如何打印两行之间的所有行,第一行以一个模式开始,最后一行以另一个模式结束?
更新
我想提到这个文档是 HTML 是一个错误。我好像触动了神经,所以忘了吧。除了打印文本文档的一部分之外,我并不想解析 HTML 或对其执行任何操作。
考虑这个例子:
aaa
bbb
pattern1
aaa pattern2
bbb
ccc
pattern2
ddd
eee
pattern1
fff
ggg
现在,我想打印从pattern1
一行开头开始到pattern2
另一行开头开始的第一个实例之间的所有内容。我想在输出中包含pattern1
和行,但我不希望该行之后有任何内容。pattern2
pattern2
pattern2
可以在该部分的某一行中找到。我不想就此停止,但是通过用 指示行的开头可以轻松解决这个问题^
。
pattern1
出现在 后面的另一行pattern2
,但我根本不想看它。我只是在寻找之间的一切第一的的实例pattern1
和第一个实例pattern2
,包括在内。
我发现某物这几乎让我到达那里使用sed
:
sed -n '/^pattern1/,/^pattern2/p' inputfile.txt
...但是在下一个实例中再次开始打印pattern1
我可以想到一种使用grep -n ... | cut -f1 -d:
两次来获取两个行号tail
并head
获取我想要的部分的方法,但我希望有一种更干净的方法。也许awk
是完成这项任务的更好工具?
当我让它工作时,我希望把它绑在一个git
钩子上。我也不知道该怎么做,但我仍在阅读和搜索:)
谢谢。
答案1
您可以使用sed
退出某个模式sed '/pattern/q'
,因此您只需要匹配,然后在第二个模式匹配处退出:
sed -n '/^pattern1/,/^pattern2/{p;/^pattern2/q}'
这样只会显示第一个块。使用子命令^pattern2
可确保sed
仅在匹配 后才退出^pattern1
。这两个^pattern2
匹配可以合并:
sed -n '/^pattern1/,${p;/^pattern2/q}'
答案2
作为一种通用方法,使用sed
,可以轻松地从一个匹配项打印到另一个匹配项(包含在内):
$ seq 1 100 > test
$ sed -n '/^12$/,/^15$/p' test
12
13
14
15
使用 awk,您可以执行相同的操作,如下所示:
$ awk '/^12$/{flag=1}/^15$/{print;flag=0}flag' test
12
13
14
15
您可以像这样使这些不包含在内:
$ awk '/^12$/{flag=1;next}/^15$/{flag=0}flag' test
13
14
$ sed -n '/^12$/,/^15$/p' test | sed '1d;$d'
13
14