How to print lines between two patterns, inclusive or exclusive (in sed, AWK or Perl)?

后端 未结 8 2295
生来不讨喜
生来不讨喜 2020-11-21 05:37

I have a file like the following and I would like to print the lines between two given patterns PAT1 and PAT2.



        
8条回答
  •  清酒与你
    2020-11-21 06:01

    Using grep with PCRE (where available) to print markers and lines between markers:

    $ grep -Pzo "(?s)(PAT1(.*?)(PAT2|\Z))" file
    PAT1
    3    - first block
    4
    PAT2
    PAT1
    7    - second block
    PAT2
    PAT1
    10    - third block
    
    • -P perl-regexp, PCRE. Not in all grep variants
    • -z Treat the input as a set of lines, each terminated by a zero byte instead of a newline
    • -o print only matching
    • (?s) DotAll, ie. dot finds newlines as well
    • (.*?) nongreedy find
    • \Z Match only at end of string, or before newline at the end

    Print lines between markers excluding end marker:

    $ grep -Pzo "(?s)(PAT1(.*?)(?=(\nPAT2|\Z)))" file
    PAT1
    3    - first block
    4
    PAT1
    7    - second block
    PAT1
    10    - third block
    
    • (.*?)(?=(\nPAT2|\Z)) nongreedy find with lookahead for \nPAT2 and \Z

    Print lines between markers excluding markers:

    $ grep -Pzo "(?s)((?<=PAT1\n)(.*?)(?=(\nPAT2|\Z)))" file
    3    - first block
    4
    7    - second block
    10    - third block
    
    • (?<=PAT1\n) positive lookbehind for PAT1\n

    Print lines between markers excluding start marker:

    $ grep -Pzo "(?s)((?<=PAT1\n)(.*?)(PAT2|\Z))" file
    3    - first block
    4
    PAT2
    7    - second block
    PAT2
    10    - third block
    

提交回复
热议问题