How to print lines between pattern1 and 2nd match of pattern2?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP












4















Test file is given below:



PATTERN1
a
b
c
PATTERN2
d
e
f
PATTERN2
g
h


I want to print line between PATTERN1 and 2nd match of PATTERN2:



PATTERN1
a
b
c
PATTERN2
d
e
f
PATTERN2









share|improve this question




























    4















    Test file is given below:



    PATTERN1
    a
    b
    c
    PATTERN2
    d
    e
    f
    PATTERN2
    g
    h


    I want to print line between PATTERN1 and 2nd match of PATTERN2:



    PATTERN1
    a
    b
    c
    PATTERN2
    d
    e
    f
    PATTERN2









    share|improve this question


























      4












      4








      4


      0






      Test file is given below:



      PATTERN1
      a
      b
      c
      PATTERN2
      d
      e
      f
      PATTERN2
      g
      h


      I want to print line between PATTERN1 and 2nd match of PATTERN2:



      PATTERN1
      a
      b
      c
      PATTERN2
      d
      e
      f
      PATTERN2









      share|improve this question
















      Test file is given below:



      PATTERN1
      a
      b
      c
      PATTERN2
      d
      e
      f
      PATTERN2
      g
      h


      I want to print line between PATTERN1 and 2nd match of PATTERN2:



      PATTERN1
      a
      b
      c
      PATTERN2
      d
      e
      f
      PATTERN2






      text-processing awk sed






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jun 28 '16 at 11:50









      jimmij

      32.3k875109




      32.3k875109










      asked Jun 28 '16 at 11:04









      sachinsachin

      686




      686




















          4 Answers
          4






          active

          oldest

          votes


















          6














          Here's one way to do it with sed:



          sed '/PATTERN1/,$!d;/PATTERN2/x;//x;q;;g;' infile


          This just deletes all lines (if any) up to the first occurrence of PATTERN1 and then, on each line that matches PATTERN2 it exchanges buffers. If the new pattern space also matches, it means it's the 2nd occurrence so it exchanges back and quits (after auto-printing). If it doesn't match it means it's the 1st occurrence so it copies the hold space content over the pattern space via g (so now there's a line matching PATTERN2 in the hold buffer) and goes on...

          and another way with awk:



          awk '/PATTERN1/t=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile


          It starts printing and counting lines matching PATTERN2 only when encountering a line matching PATTERN1 and exits when counter reaches 2.






          share|improve this answer

























          • in my case PATTERN1 is a variable. means xx=PATTERN1 so i want to use $xx instead of PATTERN1. but the awk command is not working with it. can you help me. i tried awk '/$xx/t=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile but it is not working.

            – sachin
            Jun 29 '16 at 3:52












          • @sachin - awk -v m="$xx" '$0~mt=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile

            – don_crissti
            Jun 29 '16 at 8:58












          • in another case, it should print data only if the PATTERN1 start the line. any solution ?

            – sachin
            Jul 8 '16 at 4:06












          • please provide solution to find the pattern at the start of line in the given command. awk -v m="$xx" '$0~mt=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile . because in my case the pattern 1 is a variable and coming in the start of line.

            – sachin
            Jul 8 '16 at 11:37












          • thanks for the reply, its working. can you please explain the whole command ?

            – sachin
            Jul 8 '16 at 11:48


















          5














          The right tool for this job is pcregrep:



          pcregrep -M 'PATTERN1(.|n)*PATTERN2' file


          where option -M allows pattern to match more than one line and (.|n)* match any character or newline zero or more times.



          Notice that we took advantage of the greediness of the grep. If you would want to print form pattern1 up to the first occurrence of the pattern2, then non-greedy *? should be used instead of *.



          As a generalization, to print up to the nth occurrence of PATTERN2:



          pcregrep -M 'PATTERN1((.|n)*?PATTERN2)n' file


          Change n to actual number you need.






          share|improve this answer

























          • As you are using multiline flag, so why not just pcregrep -M 'PATTERN1.*PATTERN2' file?

            – heemayl
            Jun 29 '16 at 1:51











          • n my case PATTERN1 is a variable. means xx=PATTERN1 so i want to use $xx instead of PATTERN1. but the command provided by you , is not working with it. can you help me. i tried pcregrep -M '$xx((.|n)*?PATTERN2)2' file infile but it is not working

            – sachin
            Jun 29 '16 at 3:57











          • @heemayl Because you have to provide both: -M and n, otherwise it doesn't work.

            – jimmij
            Jun 29 '16 at 7:49











          • @sachin Try pcregrep -M "$xx"'((.|n)*?PATTERN2)2' file. The variable have to be inside double quotes, otherwise it is not expanded.

            – jimmij
            Jun 29 '16 at 7:51


















          5














          Just use flags:



          $ awk '/PATTERN1/flag=2;next flag; /PATTERN2/flag--' file
          a
          b
          c
          PATTERN2
          d
          e
          f
          PATTERN2


          That is: when you find PATTERN1 set the flag to a positive value; in particular, 2. Then, when you find PATTERN2, decrease that flag in one. This way, it will exhaust after the second match. In between, use flag as a value that triggers the print $0 when it has a true value (2 or 1).






          share|improve this answer























          • This will fail in any of the following circumstances: 1) if there's at least one line matching PATTERN2 before the line matching PATTERN1 (but not immediately before it) 2) if there are more than two lines matching PATTERN2 after the line matching PATTERN1 and the third line matching PATTERN2 isn't the last line in the file or 3) if there's a second line matching PATTERN1 in between the first two (of several) lines matching PATTERN2 that follow the first line matching PATTERN1

            – don_crissti
            Jun 28 '16 at 20:29












          • Would it be possible to not print the last PATTERN2?

            – Markus Lindberg
            Jun 18 '18 at 15:14











          • @MarkusLindberg you should either create some kind of buffering (otherwise, how do you know if it is the last PATTERN2?) or read the file backwards

            – fedorqui
            Jul 4 '18 at 6:39


















          2














          If we told regarding sed is to much easy to collect nesessary lines then print



          sed -n '
          /PATTERN1/
          :1
          $!N
          /(PATTERN2).*1/!b1
          p

          ' file





          share|improve this answer






















            Your Answer








            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "106"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f292573%2fhow-to-print-lines-between-pattern1-and-2nd-match-of-pattern2%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            4 Answers
            4






            active

            oldest

            votes








            4 Answers
            4






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            6














            Here's one way to do it with sed:



            sed '/PATTERN1/,$!d;/PATTERN2/x;//x;q;;g;' infile


            This just deletes all lines (if any) up to the first occurrence of PATTERN1 and then, on each line that matches PATTERN2 it exchanges buffers. If the new pattern space also matches, it means it's the 2nd occurrence so it exchanges back and quits (after auto-printing). If it doesn't match it means it's the 1st occurrence so it copies the hold space content over the pattern space via g (so now there's a line matching PATTERN2 in the hold buffer) and goes on...

            and another way with awk:



            awk '/PATTERN1/t=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile


            It starts printing and counting lines matching PATTERN2 only when encountering a line matching PATTERN1 and exits when counter reaches 2.






            share|improve this answer

























            • in my case PATTERN1 is a variable. means xx=PATTERN1 so i want to use $xx instead of PATTERN1. but the awk command is not working with it. can you help me. i tried awk '/$xx/t=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile but it is not working.

              – sachin
              Jun 29 '16 at 3:52












            • @sachin - awk -v m="$xx" '$0~mt=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile

              – don_crissti
              Jun 29 '16 at 8:58












            • in another case, it should print data only if the PATTERN1 start the line. any solution ?

              – sachin
              Jul 8 '16 at 4:06












            • please provide solution to find the pattern at the start of line in the given command. awk -v m="$xx" '$0~mt=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile . because in my case the pattern 1 is a variable and coming in the start of line.

              – sachin
              Jul 8 '16 at 11:37












            • thanks for the reply, its working. can you please explain the whole command ?

              – sachin
              Jul 8 '16 at 11:48















            6














            Here's one way to do it with sed:



            sed '/PATTERN1/,$!d;/PATTERN2/x;//x;q;;g;' infile


            This just deletes all lines (if any) up to the first occurrence of PATTERN1 and then, on each line that matches PATTERN2 it exchanges buffers. If the new pattern space also matches, it means it's the 2nd occurrence so it exchanges back and quits (after auto-printing). If it doesn't match it means it's the 1st occurrence so it copies the hold space content over the pattern space via g (so now there's a line matching PATTERN2 in the hold buffer) and goes on...

            and another way with awk:



            awk '/PATTERN1/t=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile


            It starts printing and counting lines matching PATTERN2 only when encountering a line matching PATTERN1 and exits when counter reaches 2.






            share|improve this answer

























            • in my case PATTERN1 is a variable. means xx=PATTERN1 so i want to use $xx instead of PATTERN1. but the awk command is not working with it. can you help me. i tried awk '/$xx/t=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile but it is not working.

              – sachin
              Jun 29 '16 at 3:52












            • @sachin - awk -v m="$xx" '$0~mt=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile

              – don_crissti
              Jun 29 '16 at 8:58












            • in another case, it should print data only if the PATTERN1 start the line. any solution ?

              – sachin
              Jul 8 '16 at 4:06












            • please provide solution to find the pattern at the start of line in the given command. awk -v m="$xx" '$0~mt=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile . because in my case the pattern 1 is a variable and coming in the start of line.

              – sachin
              Jul 8 '16 at 11:37












            • thanks for the reply, its working. can you please explain the whole command ?

              – sachin
              Jul 8 '16 at 11:48













            6












            6








            6







            Here's one way to do it with sed:



            sed '/PATTERN1/,$!d;/PATTERN2/x;//x;q;;g;' infile


            This just deletes all lines (if any) up to the first occurrence of PATTERN1 and then, on each line that matches PATTERN2 it exchanges buffers. If the new pattern space also matches, it means it's the 2nd occurrence so it exchanges back and quits (after auto-printing). If it doesn't match it means it's the 1st occurrence so it copies the hold space content over the pattern space via g (so now there's a line matching PATTERN2 in the hold buffer) and goes on...

            and another way with awk:



            awk '/PATTERN1/t=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile


            It starts printing and counting lines matching PATTERN2 only when encountering a line matching PATTERN1 and exits when counter reaches 2.






            share|improve this answer















            Here's one way to do it with sed:



            sed '/PATTERN1/,$!d;/PATTERN2/x;//x;q;;g;' infile


            This just deletes all lines (if any) up to the first occurrence of PATTERN1 and then, on each line that matches PATTERN2 it exchanges buffers. If the new pattern space also matches, it means it's the 2nd occurrence so it exchanges back and quits (after auto-printing). If it doesn't match it means it's the 1st occurrence so it copies the hold space content over the pattern space via g (so now there's a line matching PATTERN2 in the hold buffer) and goes on...

            and another way with awk:



            awk '/PATTERN1/t=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile


            It starts printing and counting lines matching PATTERN2 only when encountering a line matching PATTERN1 and exits when counter reaches 2.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Jun 28 '16 at 12:22

























            answered Jun 28 '16 at 11:30









            don_crisstidon_crissti

            51.6k15141168




            51.6k15141168












            • in my case PATTERN1 is a variable. means xx=PATTERN1 so i want to use $xx instead of PATTERN1. but the awk command is not working with it. can you help me. i tried awk '/$xx/t=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile but it is not working.

              – sachin
              Jun 29 '16 at 3:52












            • @sachin - awk -v m="$xx" '$0~mt=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile

              – don_crissti
              Jun 29 '16 at 8:58












            • in another case, it should print data only if the PATTERN1 start the line. any solution ?

              – sachin
              Jul 8 '16 at 4:06












            • please provide solution to find the pattern at the start of line in the given command. awk -v m="$xx" '$0~mt=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile . because in my case the pattern 1 is a variable and coming in the start of line.

              – sachin
              Jul 8 '16 at 11:37












            • thanks for the reply, its working. can you please explain the whole command ?

              – sachin
              Jul 8 '16 at 11:48

















            • in my case PATTERN1 is a variable. means xx=PATTERN1 so i want to use $xx instead of PATTERN1. but the awk command is not working with it. can you help me. i tried awk '/$xx/t=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile but it is not working.

              – sachin
              Jun 29 '16 at 3:52












            • @sachin - awk -v m="$xx" '$0~mt=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile

              – don_crissti
              Jun 29 '16 at 8:58












            • in another case, it should print data only if the PATTERN1 start the line. any solution ?

              – sachin
              Jul 8 '16 at 4:06












            • please provide solution to find the pattern at the start of line in the given command. awk -v m="$xx" '$0~mt=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile . because in my case the pattern 1 is a variable and coming in the start of line.

              – sachin
              Jul 8 '16 at 11:37












            • thanks for the reply, its working. can you please explain the whole command ?

              – sachin
              Jul 8 '16 at 11:48
















            in my case PATTERN1 is a variable. means xx=PATTERN1 so i want to use $xx instead of PATTERN1. but the awk command is not working with it. can you help me. i tried awk '/$xx/t=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile but it is not working.

            – sachin
            Jun 29 '16 at 3:52






            in my case PATTERN1 is a variable. means xx=PATTERN1 so i want to use $xx instead of PATTERN1. but the awk command is not working with it. can you help me. i tried awk '/$xx/t=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile but it is not working.

            – sachin
            Jun 29 '16 at 3:52














            @sachin - awk -v m="$xx" '$0~mt=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile

            – don_crissti
            Jun 29 '16 at 8:58






            @sachin - awk -v m="$xx" '$0~mt=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile

            – don_crissti
            Jun 29 '16 at 8:58














            in another case, it should print data only if the PATTERN1 start the line. any solution ?

            – sachin
            Jul 8 '16 at 4:06






            in another case, it should print data only if the PATTERN1 start the line. any solution ?

            – sachin
            Jul 8 '16 at 4:06














            please provide solution to find the pattern at the start of line in the given command. awk -v m="$xx" '$0~mt=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile . because in my case the pattern 1 is a variable and coming in the start of line.

            – sachin
            Jul 8 '16 at 11:37






            please provide solution to find the pattern at the start of line in the given command. awk -v m="$xx" '$0~mt=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile . because in my case the pattern 1 is a variable and coming in the start of line.

            – sachin
            Jul 8 '16 at 11:37














            thanks for the reply, its working. can you please explain the whole command ?

            – sachin
            Jul 8 '16 at 11:48





            thanks for the reply, its working. can you please explain the whole command ?

            – sachin
            Jul 8 '16 at 11:48













            5














            The right tool for this job is pcregrep:



            pcregrep -M 'PATTERN1(.|n)*PATTERN2' file


            where option -M allows pattern to match more than one line and (.|n)* match any character or newline zero or more times.



            Notice that we took advantage of the greediness of the grep. If you would want to print form pattern1 up to the first occurrence of the pattern2, then non-greedy *? should be used instead of *.



            As a generalization, to print up to the nth occurrence of PATTERN2:



            pcregrep -M 'PATTERN1((.|n)*?PATTERN2)n' file


            Change n to actual number you need.






            share|improve this answer

























            • As you are using multiline flag, so why not just pcregrep -M 'PATTERN1.*PATTERN2' file?

              – heemayl
              Jun 29 '16 at 1:51











            • n my case PATTERN1 is a variable. means xx=PATTERN1 so i want to use $xx instead of PATTERN1. but the command provided by you , is not working with it. can you help me. i tried pcregrep -M '$xx((.|n)*?PATTERN2)2' file infile but it is not working

              – sachin
              Jun 29 '16 at 3:57











            • @heemayl Because you have to provide both: -M and n, otherwise it doesn't work.

              – jimmij
              Jun 29 '16 at 7:49











            • @sachin Try pcregrep -M "$xx"'((.|n)*?PATTERN2)2' file. The variable have to be inside double quotes, otherwise it is not expanded.

              – jimmij
              Jun 29 '16 at 7:51















            5














            The right tool for this job is pcregrep:



            pcregrep -M 'PATTERN1(.|n)*PATTERN2' file


            where option -M allows pattern to match more than one line and (.|n)* match any character or newline zero or more times.



            Notice that we took advantage of the greediness of the grep. If you would want to print form pattern1 up to the first occurrence of the pattern2, then non-greedy *? should be used instead of *.



            As a generalization, to print up to the nth occurrence of PATTERN2:



            pcregrep -M 'PATTERN1((.|n)*?PATTERN2)n' file


            Change n to actual number you need.






            share|improve this answer

























            • As you are using multiline flag, so why not just pcregrep -M 'PATTERN1.*PATTERN2' file?

              – heemayl
              Jun 29 '16 at 1:51











            • n my case PATTERN1 is a variable. means xx=PATTERN1 so i want to use $xx instead of PATTERN1. but the command provided by you , is not working with it. can you help me. i tried pcregrep -M '$xx((.|n)*?PATTERN2)2' file infile but it is not working

              – sachin
              Jun 29 '16 at 3:57











            • @heemayl Because you have to provide both: -M and n, otherwise it doesn't work.

              – jimmij
              Jun 29 '16 at 7:49











            • @sachin Try pcregrep -M "$xx"'((.|n)*?PATTERN2)2' file. The variable have to be inside double quotes, otherwise it is not expanded.

              – jimmij
              Jun 29 '16 at 7:51













            5












            5








            5







            The right tool for this job is pcregrep:



            pcregrep -M 'PATTERN1(.|n)*PATTERN2' file


            where option -M allows pattern to match more than one line and (.|n)* match any character or newline zero or more times.



            Notice that we took advantage of the greediness of the grep. If you would want to print form pattern1 up to the first occurrence of the pattern2, then non-greedy *? should be used instead of *.



            As a generalization, to print up to the nth occurrence of PATTERN2:



            pcregrep -M 'PATTERN1((.|n)*?PATTERN2)n' file


            Change n to actual number you need.






            share|improve this answer















            The right tool for this job is pcregrep:



            pcregrep -M 'PATTERN1(.|n)*PATTERN2' file


            where option -M allows pattern to match more than one line and (.|n)* match any character or newline zero or more times.



            Notice that we took advantage of the greediness of the grep. If you would want to print form pattern1 up to the first occurrence of the pattern2, then non-greedy *? should be used instead of *.



            As a generalization, to print up to the nth occurrence of PATTERN2:



            pcregrep -M 'PATTERN1((.|n)*?PATTERN2)n' file


            Change n to actual number you need.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Jun 28 '16 at 11:55

























            answered Jun 28 '16 at 11:43









            jimmijjimmij

            32.3k875109




            32.3k875109












            • As you are using multiline flag, so why not just pcregrep -M 'PATTERN1.*PATTERN2' file?

              – heemayl
              Jun 29 '16 at 1:51











            • n my case PATTERN1 is a variable. means xx=PATTERN1 so i want to use $xx instead of PATTERN1. but the command provided by you , is not working with it. can you help me. i tried pcregrep -M '$xx((.|n)*?PATTERN2)2' file infile but it is not working

              – sachin
              Jun 29 '16 at 3:57











            • @heemayl Because you have to provide both: -M and n, otherwise it doesn't work.

              – jimmij
              Jun 29 '16 at 7:49











            • @sachin Try pcregrep -M "$xx"'((.|n)*?PATTERN2)2' file. The variable have to be inside double quotes, otherwise it is not expanded.

              – jimmij
              Jun 29 '16 at 7:51

















            • As you are using multiline flag, so why not just pcregrep -M 'PATTERN1.*PATTERN2' file?

              – heemayl
              Jun 29 '16 at 1:51











            • n my case PATTERN1 is a variable. means xx=PATTERN1 so i want to use $xx instead of PATTERN1. but the command provided by you , is not working with it. can you help me. i tried pcregrep -M '$xx((.|n)*?PATTERN2)2' file infile but it is not working

              – sachin
              Jun 29 '16 at 3:57











            • @heemayl Because you have to provide both: -M and n, otherwise it doesn't work.

              – jimmij
              Jun 29 '16 at 7:49











            • @sachin Try pcregrep -M "$xx"'((.|n)*?PATTERN2)2' file. The variable have to be inside double quotes, otherwise it is not expanded.

              – jimmij
              Jun 29 '16 at 7:51
















            As you are using multiline flag, so why not just pcregrep -M 'PATTERN1.*PATTERN2' file?

            – heemayl
            Jun 29 '16 at 1:51





            As you are using multiline flag, so why not just pcregrep -M 'PATTERN1.*PATTERN2' file?

            – heemayl
            Jun 29 '16 at 1:51













            n my case PATTERN1 is a variable. means xx=PATTERN1 so i want to use $xx instead of PATTERN1. but the command provided by you , is not working with it. can you help me. i tried pcregrep -M '$xx((.|n)*?PATTERN2)2' file infile but it is not working

            – sachin
            Jun 29 '16 at 3:57





            n my case PATTERN1 is a variable. means xx=PATTERN1 so i want to use $xx instead of PATTERN1. but the command provided by you , is not working with it. can you help me. i tried pcregrep -M '$xx((.|n)*?PATTERN2)2' file infile but it is not working

            – sachin
            Jun 29 '16 at 3:57













            @heemayl Because you have to provide both: -M and n, otherwise it doesn't work.

            – jimmij
            Jun 29 '16 at 7:49





            @heemayl Because you have to provide both: -M and n, otherwise it doesn't work.

            – jimmij
            Jun 29 '16 at 7:49













            @sachin Try pcregrep -M "$xx"'((.|n)*?PATTERN2)2' file. The variable have to be inside double quotes, otherwise it is not expanded.

            – jimmij
            Jun 29 '16 at 7:51





            @sachin Try pcregrep -M "$xx"'((.|n)*?PATTERN2)2' file. The variable have to be inside double quotes, otherwise it is not expanded.

            – jimmij
            Jun 29 '16 at 7:51











            5














            Just use flags:



            $ awk '/PATTERN1/flag=2;next flag; /PATTERN2/flag--' file
            a
            b
            c
            PATTERN2
            d
            e
            f
            PATTERN2


            That is: when you find PATTERN1 set the flag to a positive value; in particular, 2. Then, when you find PATTERN2, decrease that flag in one. This way, it will exhaust after the second match. In between, use flag as a value that triggers the print $0 when it has a true value (2 or 1).






            share|improve this answer























            • This will fail in any of the following circumstances: 1) if there's at least one line matching PATTERN2 before the line matching PATTERN1 (but not immediately before it) 2) if there are more than two lines matching PATTERN2 after the line matching PATTERN1 and the third line matching PATTERN2 isn't the last line in the file or 3) if there's a second line matching PATTERN1 in between the first two (of several) lines matching PATTERN2 that follow the first line matching PATTERN1

              – don_crissti
              Jun 28 '16 at 20:29












            • Would it be possible to not print the last PATTERN2?

              – Markus Lindberg
              Jun 18 '18 at 15:14











            • @MarkusLindberg you should either create some kind of buffering (otherwise, how do you know if it is the last PATTERN2?) or read the file backwards

              – fedorqui
              Jul 4 '18 at 6:39















            5














            Just use flags:



            $ awk '/PATTERN1/flag=2;next flag; /PATTERN2/flag--' file
            a
            b
            c
            PATTERN2
            d
            e
            f
            PATTERN2


            That is: when you find PATTERN1 set the flag to a positive value; in particular, 2. Then, when you find PATTERN2, decrease that flag in one. This way, it will exhaust after the second match. In between, use flag as a value that triggers the print $0 when it has a true value (2 or 1).






            share|improve this answer























            • This will fail in any of the following circumstances: 1) if there's at least one line matching PATTERN2 before the line matching PATTERN1 (but not immediately before it) 2) if there are more than two lines matching PATTERN2 after the line matching PATTERN1 and the third line matching PATTERN2 isn't the last line in the file or 3) if there's a second line matching PATTERN1 in between the first two (of several) lines matching PATTERN2 that follow the first line matching PATTERN1

              – don_crissti
              Jun 28 '16 at 20:29












            • Would it be possible to not print the last PATTERN2?

              – Markus Lindberg
              Jun 18 '18 at 15:14











            • @MarkusLindberg you should either create some kind of buffering (otherwise, how do you know if it is the last PATTERN2?) or read the file backwards

              – fedorqui
              Jul 4 '18 at 6:39













            5












            5








            5







            Just use flags:



            $ awk '/PATTERN1/flag=2;next flag; /PATTERN2/flag--' file
            a
            b
            c
            PATTERN2
            d
            e
            f
            PATTERN2


            That is: when you find PATTERN1 set the flag to a positive value; in particular, 2. Then, when you find PATTERN2, decrease that flag in one. This way, it will exhaust after the second match. In between, use flag as a value that triggers the print $0 when it has a true value (2 or 1).






            share|improve this answer













            Just use flags:



            $ awk '/PATTERN1/flag=2;next flag; /PATTERN2/flag--' file
            a
            b
            c
            PATTERN2
            d
            e
            f
            PATTERN2


            That is: when you find PATTERN1 set the flag to a positive value; in particular, 2. Then, when you find PATTERN2, decrease that flag in one. This way, it will exhaust after the second match. In between, use flag as a value that triggers the print $0 when it has a true value (2 or 1).







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Jun 28 '16 at 13:11









            fedorquifedorqui

            4,20222158




            4,20222158












            • This will fail in any of the following circumstances: 1) if there's at least one line matching PATTERN2 before the line matching PATTERN1 (but not immediately before it) 2) if there are more than two lines matching PATTERN2 after the line matching PATTERN1 and the third line matching PATTERN2 isn't the last line in the file or 3) if there's a second line matching PATTERN1 in between the first two (of several) lines matching PATTERN2 that follow the first line matching PATTERN1

              – don_crissti
              Jun 28 '16 at 20:29












            • Would it be possible to not print the last PATTERN2?

              – Markus Lindberg
              Jun 18 '18 at 15:14











            • @MarkusLindberg you should either create some kind of buffering (otherwise, how do you know if it is the last PATTERN2?) or read the file backwards

              – fedorqui
              Jul 4 '18 at 6:39

















            • This will fail in any of the following circumstances: 1) if there's at least one line matching PATTERN2 before the line matching PATTERN1 (but not immediately before it) 2) if there are more than two lines matching PATTERN2 after the line matching PATTERN1 and the third line matching PATTERN2 isn't the last line in the file or 3) if there's a second line matching PATTERN1 in between the first two (of several) lines matching PATTERN2 that follow the first line matching PATTERN1

              – don_crissti
              Jun 28 '16 at 20:29












            • Would it be possible to not print the last PATTERN2?

              – Markus Lindberg
              Jun 18 '18 at 15:14











            • @MarkusLindberg you should either create some kind of buffering (otherwise, how do you know if it is the last PATTERN2?) or read the file backwards

              – fedorqui
              Jul 4 '18 at 6:39
















            This will fail in any of the following circumstances: 1) if there's at least one line matching PATTERN2 before the line matching PATTERN1 (but not immediately before it) 2) if there are more than two lines matching PATTERN2 after the line matching PATTERN1 and the third line matching PATTERN2 isn't the last line in the file or 3) if there's a second line matching PATTERN1 in between the first two (of several) lines matching PATTERN2 that follow the first line matching PATTERN1

            – don_crissti
            Jun 28 '16 at 20:29






            This will fail in any of the following circumstances: 1) if there's at least one line matching PATTERN2 before the line matching PATTERN1 (but not immediately before it) 2) if there are more than two lines matching PATTERN2 after the line matching PATTERN1 and the third line matching PATTERN2 isn't the last line in the file or 3) if there's a second line matching PATTERN1 in between the first two (of several) lines matching PATTERN2 that follow the first line matching PATTERN1

            – don_crissti
            Jun 28 '16 at 20:29














            Would it be possible to not print the last PATTERN2?

            – Markus Lindberg
            Jun 18 '18 at 15:14





            Would it be possible to not print the last PATTERN2?

            – Markus Lindberg
            Jun 18 '18 at 15:14













            @MarkusLindberg you should either create some kind of buffering (otherwise, how do you know if it is the last PATTERN2?) or read the file backwards

            – fedorqui
            Jul 4 '18 at 6:39





            @MarkusLindberg you should either create some kind of buffering (otherwise, how do you know if it is the last PATTERN2?) or read the file backwards

            – fedorqui
            Jul 4 '18 at 6:39











            2














            If we told regarding sed is to much easy to collect nesessary lines then print



            sed -n '
            /PATTERN1/
            :1
            $!N
            /(PATTERN2).*1/!b1
            p

            ' file





            share|improve this answer



























              2














              If we told regarding sed is to much easy to collect nesessary lines then print



              sed -n '
              /PATTERN1/
              :1
              $!N
              /(PATTERN2).*1/!b1
              p

              ' file





              share|improve this answer

























                2












                2








                2







                If we told regarding sed is to much easy to collect nesessary lines then print



                sed -n '
                /PATTERN1/
                :1
                $!N
                /(PATTERN2).*1/!b1
                p

                ' file





                share|improve this answer













                If we told regarding sed is to much easy to collect nesessary lines then print



                sed -n '
                /PATTERN1/
                :1
                $!N
                /(PATTERN2).*1/!b1
                p

                ' file






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Jun 28 '16 at 13:23









                CostasCostas

                12.7k1129




                12.7k1129



























                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Unix & Linux Stack Exchange!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f292573%2fhow-to-print-lines-between-pattern1-and-2nd-match-of-pattern2%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown






                    Popular posts from this blog

                    How to check contact read email or not when send email to Individual?

                    Displaying single band from multi-band raster using QGIS

                    How many registers does an x86_64 CPU actually have?