How can I set the grep after context to be “until the next blank line”?

后端 未结 4 1083
伪装坚强ぢ
伪装坚强ぢ 2021-01-30 13:31

With grep I know how to set the context to a fixed number of lines. Is it possible to show a context based on an arbitrary string condition, like set after-context to \"until th

相关标签:
4条回答
  • 2021-01-30 13:38

    It sounds like you need sed:

    sed -n '/pattern/,/^$/p' file
    

    Don't print by default (-n). For lines that match /pattern/ up to an empty line /^$/, print.

    0 讨论(0)
  • 2021-01-30 13:44

    Personally I like the answer from @William Pursell as the before context is often useful (eg when grepping for things in ini files). If you actually want only the after context with awk you can do this:

    $ cat demo.ini 
    [foo]
    aaa = 1
    bbb = 2
    ccc = 3
    
    [bar]
    eee = 8
    fff = 0
    ggg = 1
    
    [baz]
    xxx = 1
    yyy = 0
    zzz = 2
    $ awk '/bar/,/^$/' demo.ini 
    [bar]
    eee = 8
    fff = 0
    ggg = 1
    
    $ awk '/fff/,/^$/' demo.ini 
    fff = 0
    ggg = 1
    
    $
    

    Compare with the RS= version:

    $ awk '/bar/' RS= demo.ini 
    [bar]
    eee = 8
    fff = 0
    ggg = 1
    $ awk '/fff/' RS= demo.ini 
    [bar]
    eee = 8
    fff = 0
    ggg = 1
    
    0 讨论(0)
  • 2021-01-30 13:46

    A simple solution is:

    awk '/pattern/' RS= input-file
    

    Setting RS to the empty string makes awk treat blank lines as the record separator, and the simple rule /pattern/ causes awk to print any record that matches the pattern, which can be any extended regular expression.

    0 讨论(0)
  • 2021-01-30 14:01

    Here's a (tested) awk solution, separated onto multiple lines for readability:

    awk '/pattern/ {do_print=1}
         do_print==1 {print}  
         NF==0 {do_print=0}' input_file
    

    This script will also print the blank line so it's easier to visually separate the different matched blocks. If you don't want the blank line, swap the 2 lines do_print==1 {print} and NF==0 {do_print=0}

    Explanation:

    • awk: invoke the awk tool - it evaluates the input one line at a time sequentially.
    • '...'.: everything enclosed by the single quotes is given to awk as instructions. In this case we perform the quoted instructions on each line.
    • /pattern/ {do_print=1}: whenever a line contains "pattern", turn on the do_print flag
    • do_print==1 {print}: if the do_print flag is set to on, print the current line.
    • NF==0 {do_print=0}: NF stands for Number of Fields. awk delimits each line by spaces and tabs by default to break a line into fields. In this case trivially a blank line has no fields - so we turn off the do_print flag to stop printing when we see a line with NF == 0
    0 讨论(0)
提交回复
热议问题