正则表达式awk匹配模式,跳过第一次出现的endpat

时间:2015-07-17 02:13:01

标签: regex awk

我有问题。我想匹配两种模式之间的线条,包括在内。我能做到。让我们说这就是我所拥有的:

art
subject

Course Material
paint
brush
easel
beret

art

Skills learned
oil
pastel
ink
chalk


math
subject

Course Material
book
calculator
etc...

我将使用标准awk '/^art/ , /subject/' file并获取

art 
subject

art

Skills learned
oil
pastel
ink
chalk


math
subject

这是我能做的最好的事情。问题在于它将艺术描述分为两部分。我的问题是:

  • 如何使用第一个艺术比赛,跳过第一个纪律比赛,然后使用第二个纪律比赛?

2 个答案:

答案 0 :(得分:1)

这将从art开始打印,直到找到下一个subject

awk '/^art/{f=1;j=1;} f{print} /subject/{if(j)i++; if(i%2==0){f=0;j=0;}}' filename    #j is used as a flag.

输出:

art
subject

Course Material
paint
brush
easel
beret

art

Skills learned
oil
pastel
ink
chalk


math
subject

如果您不想打印mathsubject,最好以@JonathanLeffler回答。

答案 1 :(得分:1)

此代码似乎可以正常工作,但我不禁觉得创建一个更容易解析的输出格式会更好。

script.awk

/art/       { print; art++; next }
/subject/   { if (art < 3 && subject < 2) { print; subject++ } next }
            { if (art < 3 && subject < 2) print }

如果该行包含art,请将其打印并递增“art”计数,然后跳转到下一行。如果该行包含“主题” - 那么如果艺术计数小于3并且主题计数小于2,则打印该行并增加主题计数,然后跳转到下一行。否则,如果艺术品数量少于3且主题数量小于2,则打印该行。

样品运行

$ awk -f script.awk data
art
subject

Course Material
paint
brush
easel
beret

art

Skills learned
oil
pastel
ink
chalk


math
subject
$

此代码与示例数据有点过分关联。 '艺术&lt; 3'条件应该是'艺术&gt; 0&amp;&amp;艺术&lt; 3' 。您还希望能够选择关键字。

BEGIN       { kw1 = "art"; kw2 = "subject" }
$1 ~ kw1    { print; nkw1++; next}
$1 ~ kw2    { if (nkw1 > 0 && nkw1 < 3 && nkw2 < 2) { print; nkw2++ } next }
            { if (nkw1 > 0 && nkw1 < 3 && nkw2 < 2) print }

最后消除mathsubject行也很好。为此,我们需要一个更复杂的脚本,在打印前保存一行,记住空白行也需要打印。

修订script.awk

BEGIN       { kw1 = "art"; kw2 = "subject" }
$1 ~ kw1    { old = $0; nkw1++; next}
$1 ~ kw2    { if (nkw1 > 0 && nkw1 < 3 && nkw2 < 2)
              { if (nkw2 == 0) print old; old = $0; nkw2++ }
              next
            }
            { if (nkw1 > 0 && nkw1 < 3 && nkw2 < 2) { print old; old = $0 } }

扩展data文件

english
subject

Course material
To Kill a Mockingbird
To Set a Watchman
Huckleberry Finn
Tom Sawyer

english

Skills learned
comprehension
dialectical analysis

art
subject

Course Material
paint
brush
easel
beret

art

Skills learned
oil
pastel
ink
chalk


math
subject

Course Material
book
calculator
etc...

修改样本输出

$ awk -f script.awk data
art
subject

Course Material
paint
brush
easel
beret
art

Skills learned
oil
pastel
ink
chalk


$

修改后的脚本只打印出第一个art块。如果文件中还有其他此类块,则不会打印它们(但也不会打印多余的材料)。

您可以通过修改BEGIN块来安排将关键字传递给脚本,以检查命令行上是否设置了kw1kw2,例如:

awk -v kw1=art -v kw2=subject -f script.awk data