在两个模式之间搜索文本,其间有多行

时间:2016-01-24 13:53:38

标签: regex bash awk sed

我有一个简单的问题。我有一个包含以下内容的文件:

more random text

*foo*
there
is 
random
text
here
*foo*

foo
even
more
random
text
here
foo
more random text

(为了澄清我想要结果的部分,我在foo旁边添加了*。*不在文件中。)

我只想在foo的前两个实例之间打印出多行。

我试图找到让“foo”只出现一次然后将其删除的方法。但我没有那么远。但是我确实找到了删除所有“更随机的文本”的方法:sed'/ foo /,/ foo / p'但我找不到使用sed的方法,或awk只匹配1并打印输出。

任何人都可以帮助我吗?

3 个答案:

答案 0 :(得分:1)

使用sed:

function root()
{
    //that code
    return $root;
}

说明:

$ sed -n '/foo/{:a;n;/foo/q;p;ba}' infile
there
is
random
text
here

有些人抱怨单行的牙套;在这些情况下,这应该有效:

/foo/ {     # If we match "foo"
    :a      # Label to branch to
    n       # Discard current line, read next line (does not print because of -n)
    /foo/q  # If we match the closing "foo", then quit
    p       # Print line (is a line between two "foo"s)
    ba      # Branch to :a
}

答案 1 :(得分:0)

$ awk '/foo/{++c;next} c==1' file
there
is
random
text
here

$ awk '/foo/{++c;next} c==3' file
even
more
random
text
here

或使用GNU awk进行多字符RS,你可以这样做:

$ awk -v RS='(^|\n)[^\n]*foo[^\n]*(\n|$)' 'NR==2' file
there
is
random
text
here

$ awk -v RS='(^|\n)[^\n]*foo[^\n]*(\n|$)' 'NR==4' file
even
more
random
text
here

条件成立后,请参阅https://stackoverflow.com/a/17914105/1745001了解其他打印方式。

答案 2 :(得分:0)

由于检查“foo”(使用/foo/)是相对昂贵的,因此以下内容可以避免检查,并且可以使用所有awk名称的名称:

awk 'c==2 {next} /foo/{++c;next} c==1' file