grep lines matching a pattern, and the lines before and after the matching until different pattern

前端 未结 4 2066
我寻月下人不归
我寻月下人不归 2021-01-22 02:21
Start_pattern
abc
d End_pattern
Start_pattern
abc
d
ef
ghij 
klm
no End_pattern
Start_pattern
abc
def
hij End_pattern
Start_pattern
abc
dhi
jklm End_pattern
4条回答
  •  走了就别回头了
    2021-01-22 02:47

    With gawk, which supports multi char RS:

    gawk 'BEGIN{RS=ORS="End_pattern"}/ef/' file
    

    Output:

    Start_pattern
    abc
    d
    ef
    ghij 
    klm
    no End_pattern
    Start_pattern
    abc
    def
    hij End_pattern
    

    Explanation:

    # Split records based on the End_pattern
    BEGIN{RS=ORS="End_pattern"}
    
    # Print records that contain the search term
    /ef/
    

    Btw, for cosmetic reasons you might want to append a newline at the end out the output:

    gawk 'BEGIN{RS=ORS="End_pattern"}/ef/;END{printf "\n"}' file
    

    PS: While the above solution works with gawk only, it is also possible to achieve that with a simple awk script which is compatible to POSIX, meaning it works with any awk:

    awk '{b=b$0"\n"}/End_pattern/{if(b~/ef/){printf "%s",b};b=""}' file
    

    Explanation:

    # Append the current line plus a newline to b(uffer)
    {b=b$0"\n"}
    
    # Once End_pattern is found ...
    /End_pattern/{
        # Check if the buffer contains the search term
        if(b~/ef/){
            # Print the buffer when the term was found
            printf "%s",b
        }
        # Clear the buffer
        b=""
    }
    
    awk '{b=b$0"\n"}/End_pattern/{if(b~/ef/){printf "%s",b};b=""}' file
    

提交回复
热议问题