首页 > 解决方案 > 如何从头开始删除所有行,直到达到某种模式,除了最后一个

问题描述

例子:

>"one"
>"two"
>"three"
>"title"
>12 23 14
>...

我想删除开头的所有行,直到我到达其中NF==3(awk)的行,但是名为“ title”的行,并且只在文件的开头一次,而不是重复。

谢谢

预期输出:

>"title"
>12 23 14
>...

标签: linuxbashcsh

解决方案


这样做的方法是awk按照您已经建议的方式使用。正如您所说,您想打印从第一次出现的有 3 个字段的行,这可以通过设置打印标志轻松完成(我们称之为p)'

awk '(NF==3){p=1};p' file

这将打印从第一行开始的所有内容,包含 3 个字段。

但是,您还想打印包含字符串"title"的行。这可以通过匹配这个字符串来完成:

awk '/title/{print}(NF==3){p=1};p' file

这样做的问题是,当您的文件看起来像时,“标题”一词可能会被打印两次

a          < not printed
title      < printed
a b c      < printed
title      < printed twice
e f g      < printed
h          < printed

因此,您必须在此处对您的逻辑更加小心,并将支票与何时打印的支票放在一起:

awk '(NF==3){p=1};(p || /title/)' file

这又不可靠,因为您可能有一个文件,例如:

a          < not printed
title 1    < printed
b          < not printed
title 2    < printed
a b c      < printed
h          < printed

并且您只想打印“title 2” :

awk '/title/{s=$0}(NF==3){p=1;print s};p' file

如果“标题”只是指具有 3 个字段的第一行之前的行,那么您可以

awk '(NF==3){p=1;print s};p;{s=$0}' file

或小幅加速:

awk '(NF==3){p=1;print s};p{print; next}{s=$0}' file

推荐阅读