How do I get multi-line string between two braces containing a specific search string?

前端 未结 3 1904
傲寒
傲寒 2020-12-11 09:19

I\'m looking for a quick and easy one-liner to extract all brace-delimited text-blocks containing a search string from a text file. I\'ve just about googled myself crazy on

相关标签:
3条回答
  • 2020-12-11 09:32

    Here is a modified version of this gem from 'leu' (10x leu for enlighten us). This one is doing something very similarly. Extract everything between which begin with 'DEC::PKCS7[' and ending with ']!':

    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
    

    Notes:

    • This works on single and multi-line.
    • This will have unexpected behavior if you have ']!' in the middle of the input.
    • This does not answer the question. It's already answered very well. My intentions are just to help other cases.
    0 讨论(0)
  • 2020-12-11 09:42

    This gnu-awk should work:

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

    RS='[^\n]*{\n|}' sets input record separator as any text followed by { OR a }. RT is the internal awk variable that is set to matched text based on RS regex.

    0 讨论(0)
  • 2020-12-11 09:45

    User 999999999999999999999999999999 had a nice answer using sed which I really liked, unfortunately their answer appears to have disappeared for some reason.

    Here it is for those who might be interested:

    sed '/{/{:1; /}/!{N; b1}; /event/p}; d' filepath

    Explanation:

    /{/ 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

    0 讨论(0)
提交回复
热议问题