如何在包含特定搜索字符串的两个大括号之间获得多行字符串?

时间:2015-09-15 14:18:50

标签: linux bash

我正在寻找一个快速简单的单行程序来提取包含来自文本文件的搜索字符串的所有大括号分隔的文本块。我只是在谷歌搜索自己疯狂,但每个人似乎只发布关于在没有搜索字符串的情况下在大括号之间获取文本。

我有一个大文本文件,内容如下:

blabla
blabla {
  blabla
}
blabla
blabla {
  blabla
  blablaeventblabla
}
blabla

绝大多数括号内的条目不包含搜索字符串,即" event"。

我想要提取的是每组花括号之间的所有文本(特别是包括多行匹配),但前提是所述文本还包含搜索字符串。所以输出如下:

blabla {
  blabla
  blablaeventblabla
}

我的linux命令行是/ usr / bin / bash。我一直在尝试各种grep和awk命令,但是无法让它工作:

awk '/{/,/event/,/}/' filepath

grep -iE "/{.*event.*/}" filepath

我认为这很容易,因为它是一项常见的任务。我在这里错过了什么?

3 个答案:

答案 0 :(得分:1)

这个gnu-awk应该可以工作:

awk -v RS='[^\n]*{|}' 'RT ~ /{/{p=RT} /event/{ print p $0 RT }' file
blabla {
   blabla
   blablaeventblabla
}

RS='[^\n]*{\n|}'将输入记录分隔符设置为{}之后的任何文本。 RT是内部awk变量,根据RS正则表达式设置为匹配文本。

答案 1 :(得分:1)

用户999999999999999999999999999999使用我真正喜欢的sed '/{/{:1; /}/!{N; b1}; /event/p}; d' filepath得到了一个很好的答案,不幸的是他们的回答似乎因某种原因而消失了。

这里有可能感兴趣的人:

/{/ if current line contains

说明:

then execute next block { start block :1; label for code to jump to /}/! if the line does not contain {then execute next block { start block N; add next line to pattern space b1 jump to label 1 }; end block /event/p if the pattern space contains the search string, print it (at this point the pattern space contains a full block of lines from} to {) }; end block d delete pattern space } {{1}}

答案 2 :(得分:0)

这是'leu'的这颗宝石的改良版(10x leu启发我们)。这个人做的事情非常相似。提取所有以'DEC :: PKCS7 ['开始,以']!结尾的内容:

cat file | sed '/^DEC::PKCS7\[/{s///; :1; /\]\!$/!{N; b1;}; s///;};'
Explanation:
/^DEC::PKCS7\[/             # if current line begins with 'DEC::PKCS7[' then execute next block
{                           # start block
    s///;                       # remove all upto 'DEC::PKCS7['
    :1;                         # label '1' for code to jump to
    /\]\!$/!                     # if the line does not end with ']!' then execute next block
    {                               # start block
        N;                          # add next line to pattern space
        b1;                         # jump to label 1
    };                          # end block
    s///;                       # remove all from ']!' to end of line
};                          # end block

注意:

  • 这适用于单行和多行。
  • 如果您使用'] !,这将发生意外的行为!在中间 输入。
  • 这不能回答问题。已经很好回答了。 我的意图只是帮助其他案件。