Print ranges from last occurance of a certain pattern to the first occurrence of another pattern

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











up vote
5
down vote

favorite
1












Good morning, this is extremely similar to the question Grep From the Last Occurrence of a Pattern to Another Pattern (several months old), while adding a little more detail.



I am trying to write a UNIX script for a file with multiple duplicate patterns, followed by the pattern I am looking for. However I do not have 'tac' or 'tail -r' (using the UNIX emulator, MKS Toolkit), and am looking to return the last occurrence of Pattern1 before Pattern2, followed by the data in between Pattern1 and Pattern2, and then Pattern2 also. The Patterns in this case would be 'Condition 1' and 'Condition 2':



output.out:



...
Condition 1: A
data1
Condition 1: B
data2
Condition 2: C
data3
Condition 1: D
data4
Condition 1: E
data5
Condition 2: F
...


I'd like to write an awk (or sed, but figured awk would be the right tool) script to return:



Condition 1: B
data2
Condition 2: C
Condition 1: E
data5
Condition 2: F


I figure it's some form of the line below, but I can't get the syntax right:



awk '/Condition 1/ acc = $0; /,/Condition 2/ print ?' output.out


Working the '/,/' is where I seem to be having hangups. Was wondering if anyone had any advice, would be much appreciated. Many thanks for any help and time related to this question.










share|improve this question



























    up vote
    5
    down vote

    favorite
    1












    Good morning, this is extremely similar to the question Grep From the Last Occurrence of a Pattern to Another Pattern (several months old), while adding a little more detail.



    I am trying to write a UNIX script for a file with multiple duplicate patterns, followed by the pattern I am looking for. However I do not have 'tac' or 'tail -r' (using the UNIX emulator, MKS Toolkit), and am looking to return the last occurrence of Pattern1 before Pattern2, followed by the data in between Pattern1 and Pattern2, and then Pattern2 also. The Patterns in this case would be 'Condition 1' and 'Condition 2':



    output.out:



    ...
    Condition 1: A
    data1
    Condition 1: B
    data2
    Condition 2: C
    data3
    Condition 1: D
    data4
    Condition 1: E
    data5
    Condition 2: F
    ...


    I'd like to write an awk (or sed, but figured awk would be the right tool) script to return:



    Condition 1: B
    data2
    Condition 2: C
    Condition 1: E
    data5
    Condition 2: F


    I figure it's some form of the line below, but I can't get the syntax right:



    awk '/Condition 1/ acc = $0; /,/Condition 2/ print ?' output.out


    Working the '/,/' is where I seem to be having hangups. Was wondering if anyone had any advice, would be much appreciated. Many thanks for any help and time related to this question.










    share|improve this question

























      up vote
      5
      down vote

      favorite
      1









      up vote
      5
      down vote

      favorite
      1






      1





      Good morning, this is extremely similar to the question Grep From the Last Occurrence of a Pattern to Another Pattern (several months old), while adding a little more detail.



      I am trying to write a UNIX script for a file with multiple duplicate patterns, followed by the pattern I am looking for. However I do not have 'tac' or 'tail -r' (using the UNIX emulator, MKS Toolkit), and am looking to return the last occurrence of Pattern1 before Pattern2, followed by the data in between Pattern1 and Pattern2, and then Pattern2 also. The Patterns in this case would be 'Condition 1' and 'Condition 2':



      output.out:



      ...
      Condition 1: A
      data1
      Condition 1: B
      data2
      Condition 2: C
      data3
      Condition 1: D
      data4
      Condition 1: E
      data5
      Condition 2: F
      ...


      I'd like to write an awk (or sed, but figured awk would be the right tool) script to return:



      Condition 1: B
      data2
      Condition 2: C
      Condition 1: E
      data5
      Condition 2: F


      I figure it's some form of the line below, but I can't get the syntax right:



      awk '/Condition 1/ acc = $0; /,/Condition 2/ print ?' output.out


      Working the '/,/' is where I seem to be having hangups. Was wondering if anyone had any advice, would be much appreciated. Many thanks for any help and time related to this question.










      share|improve this question















      Good morning, this is extremely similar to the question Grep From the Last Occurrence of a Pattern to Another Pattern (several months old), while adding a little more detail.



      I am trying to write a UNIX script for a file with multiple duplicate patterns, followed by the pattern I am looking for. However I do not have 'tac' or 'tail -r' (using the UNIX emulator, MKS Toolkit), and am looking to return the last occurrence of Pattern1 before Pattern2, followed by the data in between Pattern1 and Pattern2, and then Pattern2 also. The Patterns in this case would be 'Condition 1' and 'Condition 2':



      output.out:



      ...
      Condition 1: A
      data1
      Condition 1: B
      data2
      Condition 2: C
      data3
      Condition 1: D
      data4
      Condition 1: E
      data5
      Condition 2: F
      ...


      I'd like to write an awk (or sed, but figured awk would be the right tool) script to return:



      Condition 1: B
      data2
      Condition 2: C
      Condition 1: E
      data5
      Condition 2: F


      I figure it's some form of the line below, but I can't get the syntax right:



      awk '/Condition 1/ acc = $0; /,/Condition 2/ print ?' output.out


      Working the '/,/' is where I seem to be having hangups. Was wondering if anyone had any advice, would be much appreciated. Many thanks for any help and time related to this question.







      text-processing awk sed






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 21 mins ago









      don_crissti

      47.7k15126155




      47.7k15126155










      asked Nov 21 '17 at 18:54









      Henry

      546




      546




















          4 Answers
          4






          active

          oldest

          votes

















          up vote
          5
          down vote



          accepted










          Try:



          $ awk 'fa=a"n"$0 /Condition 1/a=$0; f=1 f && /Condition 2/print a; f=0' output.out 
          Condition 1: B
          data2
          Condition 2: C
          Condition 1: E
          data5
          Condition 2: F


          How it works




          • fa=a"n"$0



            If the variable f is true (nonzero), then append the current line onto the end of variable a.




          • /Condition 1/a=$0; f=1



            If the current line contains Condition 1, then set s to the current line and set variable f to 1.




          • f && /Condition 2/print a; f=0



            If f is true and the current line contains Condition 2, then print variable a and set f back to zero.







          share|improve this answer
















          • 1




            Thank you John, much appreciated. Verified that it gave the same (and correct) results as the sed and perl answers. I did not realize that I was so far off with my thinking, and that it would be more detailed with awk than I thought. Thanks again.
            – Henry
            Nov 21 '17 at 21:02










          • I'm not sure what the point of collecting the lines in a is: awk '/Condition 1/ f=1 f print /Condition 2/ f=0' accomplishes the same thing.
            – Paul Sinclair
            Nov 22 '17 at 4:03






          • 1




            @PaulSinclair It is a subtle point but that would start printing from the first occurrence of Condition 1. The OP wants to print only from the last time that Condition 1 occurs before the line containing Condition 2.
            – John1024
            Nov 22 '17 at 4:26







          • 1




            True. I missed that. Your solution is indeed the way to go.
            – Paul Sinclair
            Nov 22 '17 at 4:32

















          up vote
          5
          down vote













          When you want reverse addressing in text processing, use ex



          It's POSIX specified, and it's the scriptable form of vi (and vi's immediate predecessor)—very flexible.



          printf '%sn' 'g/Condition 2/?Condition 1?,.p' | ex output.out


          This means:



          For every line (globally) matching the pattern "Condition 2", search backward for the immediately preceding instance of "Condition 1" and print all lines from that line to the current line (.) (which is the line with "Condition 2" on it).



          Output on provided input is exactly as you describe.






          share|improve this answer




















          • Thanks Wildcard. When executing this command, it looks like it gives me the same results as the awk sed and perl commands in this thread, but double spaces the results for some reason (in Notepad++). When I try to trim with "sed '/^$/d' file.txt", no effect, so maybe something weird is going on in my environment. This is definitely very helpful though, as it looks like exactly what I was wanting to do.
            – Henry
            Nov 22 '17 at 14:36










          • @Henry, very probably you have Windows-style line endings.
            – Wildcard
            Dec 1 '17 at 17:35

















          up vote
          4
          down vote













          sed 'H;/PATTERN_1/h;/PATTERN_2/!d;x' infile


          though this assumes that any line that matches PATTERN_2 is preceded by at least one line matching PATTERN_1. For the more general case add another condition to test for PATTERN_1 presence in the pattern space before printing:



          sed 'H;/PATTERN_1/h;/PATTERN_2/!d;x;/PATTERN_1/!d' infile





          share|improve this answer




















          • Thank you Don, much appreciated. Verified that it gave the same (and correct) results as the perl and awk answers.
            – Henry
            Nov 21 '17 at 21:01

















          up vote
          4
          down vote













          Here's an evil bit of perl:



          perl -0777 -ne '
          my $c1 = qr/Condition 1/;
          my $c2 = qr/Condition 2/;
          print for map s/$c2.*?nK.*//s; $_
          grep /$c2/
          split /(?=$c1)/ms;
          ' output.out


          It:



          • reads the entire file (using the -0777 and -n options),

          • splits it where Condition 1 appears (split),

          • filters out paragraphs where Condition 2 does not appear (grep),

          • then removes from each interesting paragraph any lines following the Condition 2 line (map).





          share|improve this answer




















          • Thank you Glenn, much appreciated. Verified that it gave the same (and correct) results as the sed and awk answers.
            – Henry
            Nov 21 '17 at 21:01










          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',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          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%2f406109%2fprint-ranges-from-last-occurance-of-a-certain-pattern-to-the-first-occurrence-of%23new-answer', 'question_page');

          );

          Post as a guest






























          4 Answers
          4






          active

          oldest

          votes








          4 Answers
          4






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          5
          down vote



          accepted










          Try:



          $ awk 'fa=a"n"$0 /Condition 1/a=$0; f=1 f && /Condition 2/print a; f=0' output.out 
          Condition 1: B
          data2
          Condition 2: C
          Condition 1: E
          data5
          Condition 2: F


          How it works




          • fa=a"n"$0



            If the variable f is true (nonzero), then append the current line onto the end of variable a.




          • /Condition 1/a=$0; f=1



            If the current line contains Condition 1, then set s to the current line and set variable f to 1.




          • f && /Condition 2/print a; f=0



            If f is true and the current line contains Condition 2, then print variable a and set f back to zero.







          share|improve this answer
















          • 1




            Thank you John, much appreciated. Verified that it gave the same (and correct) results as the sed and perl answers. I did not realize that I was so far off with my thinking, and that it would be more detailed with awk than I thought. Thanks again.
            – Henry
            Nov 21 '17 at 21:02










          • I'm not sure what the point of collecting the lines in a is: awk '/Condition 1/ f=1 f print /Condition 2/ f=0' accomplishes the same thing.
            – Paul Sinclair
            Nov 22 '17 at 4:03






          • 1




            @PaulSinclair It is a subtle point but that would start printing from the first occurrence of Condition 1. The OP wants to print only from the last time that Condition 1 occurs before the line containing Condition 2.
            – John1024
            Nov 22 '17 at 4:26







          • 1




            True. I missed that. Your solution is indeed the way to go.
            – Paul Sinclair
            Nov 22 '17 at 4:32














          up vote
          5
          down vote



          accepted










          Try:



          $ awk 'fa=a"n"$0 /Condition 1/a=$0; f=1 f && /Condition 2/print a; f=0' output.out 
          Condition 1: B
          data2
          Condition 2: C
          Condition 1: E
          data5
          Condition 2: F


          How it works




          • fa=a"n"$0



            If the variable f is true (nonzero), then append the current line onto the end of variable a.




          • /Condition 1/a=$0; f=1



            If the current line contains Condition 1, then set s to the current line and set variable f to 1.




          • f && /Condition 2/print a; f=0



            If f is true and the current line contains Condition 2, then print variable a and set f back to zero.







          share|improve this answer
















          • 1




            Thank you John, much appreciated. Verified that it gave the same (and correct) results as the sed and perl answers. I did not realize that I was so far off with my thinking, and that it would be more detailed with awk than I thought. Thanks again.
            – Henry
            Nov 21 '17 at 21:02










          • I'm not sure what the point of collecting the lines in a is: awk '/Condition 1/ f=1 f print /Condition 2/ f=0' accomplishes the same thing.
            – Paul Sinclair
            Nov 22 '17 at 4:03






          • 1




            @PaulSinclair It is a subtle point but that would start printing from the first occurrence of Condition 1. The OP wants to print only from the last time that Condition 1 occurs before the line containing Condition 2.
            – John1024
            Nov 22 '17 at 4:26







          • 1




            True. I missed that. Your solution is indeed the way to go.
            – Paul Sinclair
            Nov 22 '17 at 4:32












          up vote
          5
          down vote



          accepted







          up vote
          5
          down vote



          accepted






          Try:



          $ awk 'fa=a"n"$0 /Condition 1/a=$0; f=1 f && /Condition 2/print a; f=0' output.out 
          Condition 1: B
          data2
          Condition 2: C
          Condition 1: E
          data5
          Condition 2: F


          How it works




          • fa=a"n"$0



            If the variable f is true (nonzero), then append the current line onto the end of variable a.




          • /Condition 1/a=$0; f=1



            If the current line contains Condition 1, then set s to the current line and set variable f to 1.




          • f && /Condition 2/print a; f=0



            If f is true and the current line contains Condition 2, then print variable a and set f back to zero.







          share|improve this answer












          Try:



          $ awk 'fa=a"n"$0 /Condition 1/a=$0; f=1 f && /Condition 2/print a; f=0' output.out 
          Condition 1: B
          data2
          Condition 2: C
          Condition 1: E
          data5
          Condition 2: F


          How it works




          • fa=a"n"$0



            If the variable f is true (nonzero), then append the current line onto the end of variable a.




          • /Condition 1/a=$0; f=1



            If the current line contains Condition 1, then set s to the current line and set variable f to 1.




          • f && /Condition 2/print a; f=0



            If f is true and the current line contains Condition 2, then print variable a and set f back to zero.








          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 21 '17 at 19:04









          John1024

          44.7k4101117




          44.7k4101117







          • 1




            Thank you John, much appreciated. Verified that it gave the same (and correct) results as the sed and perl answers. I did not realize that I was so far off with my thinking, and that it would be more detailed with awk than I thought. Thanks again.
            – Henry
            Nov 21 '17 at 21:02










          • I'm not sure what the point of collecting the lines in a is: awk '/Condition 1/ f=1 f print /Condition 2/ f=0' accomplishes the same thing.
            – Paul Sinclair
            Nov 22 '17 at 4:03






          • 1




            @PaulSinclair It is a subtle point but that would start printing from the first occurrence of Condition 1. The OP wants to print only from the last time that Condition 1 occurs before the line containing Condition 2.
            – John1024
            Nov 22 '17 at 4:26







          • 1




            True. I missed that. Your solution is indeed the way to go.
            – Paul Sinclair
            Nov 22 '17 at 4:32












          • 1




            Thank you John, much appreciated. Verified that it gave the same (and correct) results as the sed and perl answers. I did not realize that I was so far off with my thinking, and that it would be more detailed with awk than I thought. Thanks again.
            – Henry
            Nov 21 '17 at 21:02










          • I'm not sure what the point of collecting the lines in a is: awk '/Condition 1/ f=1 f print /Condition 2/ f=0' accomplishes the same thing.
            – Paul Sinclair
            Nov 22 '17 at 4:03






          • 1




            @PaulSinclair It is a subtle point but that would start printing from the first occurrence of Condition 1. The OP wants to print only from the last time that Condition 1 occurs before the line containing Condition 2.
            – John1024
            Nov 22 '17 at 4:26







          • 1




            True. I missed that. Your solution is indeed the way to go.
            – Paul Sinclair
            Nov 22 '17 at 4:32







          1




          1




          Thank you John, much appreciated. Verified that it gave the same (and correct) results as the sed and perl answers. I did not realize that I was so far off with my thinking, and that it would be more detailed with awk than I thought. Thanks again.
          – Henry
          Nov 21 '17 at 21:02




          Thank you John, much appreciated. Verified that it gave the same (and correct) results as the sed and perl answers. I did not realize that I was so far off with my thinking, and that it would be more detailed with awk than I thought. Thanks again.
          – Henry
          Nov 21 '17 at 21:02












          I'm not sure what the point of collecting the lines in a is: awk '/Condition 1/ f=1 f print /Condition 2/ f=0' accomplishes the same thing.
          – Paul Sinclair
          Nov 22 '17 at 4:03




          I'm not sure what the point of collecting the lines in a is: awk '/Condition 1/ f=1 f print /Condition 2/ f=0' accomplishes the same thing.
          – Paul Sinclair
          Nov 22 '17 at 4:03




          1




          1




          @PaulSinclair It is a subtle point but that would start printing from the first occurrence of Condition 1. The OP wants to print only from the last time that Condition 1 occurs before the line containing Condition 2.
          – John1024
          Nov 22 '17 at 4:26





          @PaulSinclair It is a subtle point but that would start printing from the first occurrence of Condition 1. The OP wants to print only from the last time that Condition 1 occurs before the line containing Condition 2.
          – John1024
          Nov 22 '17 at 4:26





          1




          1




          True. I missed that. Your solution is indeed the way to go.
          – Paul Sinclair
          Nov 22 '17 at 4:32




          True. I missed that. Your solution is indeed the way to go.
          – Paul Sinclair
          Nov 22 '17 at 4:32












          up vote
          5
          down vote













          When you want reverse addressing in text processing, use ex



          It's POSIX specified, and it's the scriptable form of vi (and vi's immediate predecessor)—very flexible.



          printf '%sn' 'g/Condition 2/?Condition 1?,.p' | ex output.out


          This means:



          For every line (globally) matching the pattern "Condition 2", search backward for the immediately preceding instance of "Condition 1" and print all lines from that line to the current line (.) (which is the line with "Condition 2" on it).



          Output on provided input is exactly as you describe.






          share|improve this answer




















          • Thanks Wildcard. When executing this command, it looks like it gives me the same results as the awk sed and perl commands in this thread, but double spaces the results for some reason (in Notepad++). When I try to trim with "sed '/^$/d' file.txt", no effect, so maybe something weird is going on in my environment. This is definitely very helpful though, as it looks like exactly what I was wanting to do.
            – Henry
            Nov 22 '17 at 14:36










          • @Henry, very probably you have Windows-style line endings.
            – Wildcard
            Dec 1 '17 at 17:35














          up vote
          5
          down vote













          When you want reverse addressing in text processing, use ex



          It's POSIX specified, and it's the scriptable form of vi (and vi's immediate predecessor)—very flexible.



          printf '%sn' 'g/Condition 2/?Condition 1?,.p' | ex output.out


          This means:



          For every line (globally) matching the pattern "Condition 2", search backward for the immediately preceding instance of "Condition 1" and print all lines from that line to the current line (.) (which is the line with "Condition 2" on it).



          Output on provided input is exactly as you describe.






          share|improve this answer




















          • Thanks Wildcard. When executing this command, it looks like it gives me the same results as the awk sed and perl commands in this thread, but double spaces the results for some reason (in Notepad++). When I try to trim with "sed '/^$/d' file.txt", no effect, so maybe something weird is going on in my environment. This is definitely very helpful though, as it looks like exactly what I was wanting to do.
            – Henry
            Nov 22 '17 at 14:36










          • @Henry, very probably you have Windows-style line endings.
            – Wildcard
            Dec 1 '17 at 17:35












          up vote
          5
          down vote










          up vote
          5
          down vote









          When you want reverse addressing in text processing, use ex



          It's POSIX specified, and it's the scriptable form of vi (and vi's immediate predecessor)—very flexible.



          printf '%sn' 'g/Condition 2/?Condition 1?,.p' | ex output.out


          This means:



          For every line (globally) matching the pattern "Condition 2", search backward for the immediately preceding instance of "Condition 1" and print all lines from that line to the current line (.) (which is the line with "Condition 2" on it).



          Output on provided input is exactly as you describe.






          share|improve this answer












          When you want reverse addressing in text processing, use ex



          It's POSIX specified, and it's the scriptable form of vi (and vi's immediate predecessor)—very flexible.



          printf '%sn' 'g/Condition 2/?Condition 1?,.p' | ex output.out


          This means:



          For every line (globally) matching the pattern "Condition 2", search backward for the immediately preceding instance of "Condition 1" and print all lines from that line to the current line (.) (which is the line with "Condition 2" on it).



          Output on provided input is exactly as you describe.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 21 '17 at 23:13









          Wildcard

          22.2k959156




          22.2k959156











          • Thanks Wildcard. When executing this command, it looks like it gives me the same results as the awk sed and perl commands in this thread, but double spaces the results for some reason (in Notepad++). When I try to trim with "sed '/^$/d' file.txt", no effect, so maybe something weird is going on in my environment. This is definitely very helpful though, as it looks like exactly what I was wanting to do.
            – Henry
            Nov 22 '17 at 14:36










          • @Henry, very probably you have Windows-style line endings.
            – Wildcard
            Dec 1 '17 at 17:35
















          • Thanks Wildcard. When executing this command, it looks like it gives me the same results as the awk sed and perl commands in this thread, but double spaces the results for some reason (in Notepad++). When I try to trim with "sed '/^$/d' file.txt", no effect, so maybe something weird is going on in my environment. This is definitely very helpful though, as it looks like exactly what I was wanting to do.
            – Henry
            Nov 22 '17 at 14:36










          • @Henry, very probably you have Windows-style line endings.
            – Wildcard
            Dec 1 '17 at 17:35















          Thanks Wildcard. When executing this command, it looks like it gives me the same results as the awk sed and perl commands in this thread, but double spaces the results for some reason (in Notepad++). When I try to trim with "sed '/^$/d' file.txt", no effect, so maybe something weird is going on in my environment. This is definitely very helpful though, as it looks like exactly what I was wanting to do.
          – Henry
          Nov 22 '17 at 14:36




          Thanks Wildcard. When executing this command, it looks like it gives me the same results as the awk sed and perl commands in this thread, but double spaces the results for some reason (in Notepad++). When I try to trim with "sed '/^$/d' file.txt", no effect, so maybe something weird is going on in my environment. This is definitely very helpful though, as it looks like exactly what I was wanting to do.
          – Henry
          Nov 22 '17 at 14:36












          @Henry, very probably you have Windows-style line endings.
          – Wildcard
          Dec 1 '17 at 17:35




          @Henry, very probably you have Windows-style line endings.
          – Wildcard
          Dec 1 '17 at 17:35










          up vote
          4
          down vote













          sed 'H;/PATTERN_1/h;/PATTERN_2/!d;x' infile


          though this assumes that any line that matches PATTERN_2 is preceded by at least one line matching PATTERN_1. For the more general case add another condition to test for PATTERN_1 presence in the pattern space before printing:



          sed 'H;/PATTERN_1/h;/PATTERN_2/!d;x;/PATTERN_1/!d' infile





          share|improve this answer




















          • Thank you Don, much appreciated. Verified that it gave the same (and correct) results as the perl and awk answers.
            – Henry
            Nov 21 '17 at 21:01














          up vote
          4
          down vote













          sed 'H;/PATTERN_1/h;/PATTERN_2/!d;x' infile


          though this assumes that any line that matches PATTERN_2 is preceded by at least one line matching PATTERN_1. For the more general case add another condition to test for PATTERN_1 presence in the pattern space before printing:



          sed 'H;/PATTERN_1/h;/PATTERN_2/!d;x;/PATTERN_1/!d' infile





          share|improve this answer




















          • Thank you Don, much appreciated. Verified that it gave the same (and correct) results as the perl and awk answers.
            – Henry
            Nov 21 '17 at 21:01












          up vote
          4
          down vote










          up vote
          4
          down vote









          sed 'H;/PATTERN_1/h;/PATTERN_2/!d;x' infile


          though this assumes that any line that matches PATTERN_2 is preceded by at least one line matching PATTERN_1. For the more general case add another condition to test for PATTERN_1 presence in the pattern space before printing:



          sed 'H;/PATTERN_1/h;/PATTERN_2/!d;x;/PATTERN_1/!d' infile





          share|improve this answer












          sed 'H;/PATTERN_1/h;/PATTERN_2/!d;x' infile


          though this assumes that any line that matches PATTERN_2 is preceded by at least one line matching PATTERN_1. For the more general case add another condition to test for PATTERN_1 presence in the pattern space before printing:



          sed 'H;/PATTERN_1/h;/PATTERN_2/!d;x;/PATTERN_1/!d' infile






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 21 '17 at 19:35









          don_crissti

          47.7k15126155




          47.7k15126155











          • Thank you Don, much appreciated. Verified that it gave the same (and correct) results as the perl and awk answers.
            – Henry
            Nov 21 '17 at 21:01
















          • Thank you Don, much appreciated. Verified that it gave the same (and correct) results as the perl and awk answers.
            – Henry
            Nov 21 '17 at 21:01















          Thank you Don, much appreciated. Verified that it gave the same (and correct) results as the perl and awk answers.
          – Henry
          Nov 21 '17 at 21:01




          Thank you Don, much appreciated. Verified that it gave the same (and correct) results as the perl and awk answers.
          – Henry
          Nov 21 '17 at 21:01










          up vote
          4
          down vote













          Here's an evil bit of perl:



          perl -0777 -ne '
          my $c1 = qr/Condition 1/;
          my $c2 = qr/Condition 2/;
          print for map s/$c2.*?nK.*//s; $_
          grep /$c2/
          split /(?=$c1)/ms;
          ' output.out


          It:



          • reads the entire file (using the -0777 and -n options),

          • splits it where Condition 1 appears (split),

          • filters out paragraphs where Condition 2 does not appear (grep),

          • then removes from each interesting paragraph any lines following the Condition 2 line (map).





          share|improve this answer




















          • Thank you Glenn, much appreciated. Verified that it gave the same (and correct) results as the sed and awk answers.
            – Henry
            Nov 21 '17 at 21:01














          up vote
          4
          down vote













          Here's an evil bit of perl:



          perl -0777 -ne '
          my $c1 = qr/Condition 1/;
          my $c2 = qr/Condition 2/;
          print for map s/$c2.*?nK.*//s; $_
          grep /$c2/
          split /(?=$c1)/ms;
          ' output.out


          It:



          • reads the entire file (using the -0777 and -n options),

          • splits it where Condition 1 appears (split),

          • filters out paragraphs where Condition 2 does not appear (grep),

          • then removes from each interesting paragraph any lines following the Condition 2 line (map).





          share|improve this answer




















          • Thank you Glenn, much appreciated. Verified that it gave the same (and correct) results as the sed and awk answers.
            – Henry
            Nov 21 '17 at 21:01












          up vote
          4
          down vote










          up vote
          4
          down vote









          Here's an evil bit of perl:



          perl -0777 -ne '
          my $c1 = qr/Condition 1/;
          my $c2 = qr/Condition 2/;
          print for map s/$c2.*?nK.*//s; $_
          grep /$c2/
          split /(?=$c1)/ms;
          ' output.out


          It:



          • reads the entire file (using the -0777 and -n options),

          • splits it where Condition 1 appears (split),

          • filters out paragraphs where Condition 2 does not appear (grep),

          • then removes from each interesting paragraph any lines following the Condition 2 line (map).





          share|improve this answer












          Here's an evil bit of perl:



          perl -0777 -ne '
          my $c1 = qr/Condition 1/;
          my $c2 = qr/Condition 2/;
          print for map s/$c2.*?nK.*//s; $_
          grep /$c2/
          split /(?=$c1)/ms;
          ' output.out


          It:



          • reads the entire file (using the -0777 and -n options),

          • splits it where Condition 1 appears (split),

          • filters out paragraphs where Condition 2 does not appear (grep),

          • then removes from each interesting paragraph any lines following the Condition 2 line (map).






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 21 '17 at 20:03









          glenn jackman

          48.6k366105




          48.6k366105











          • Thank you Glenn, much appreciated. Verified that it gave the same (and correct) results as the sed and awk answers.
            – Henry
            Nov 21 '17 at 21:01
















          • Thank you Glenn, much appreciated. Verified that it gave the same (and correct) results as the sed and awk answers.
            – Henry
            Nov 21 '17 at 21:01















          Thank you Glenn, much appreciated. Verified that it gave the same (and correct) results as the sed and awk answers.
          – Henry
          Nov 21 '17 at 21:01




          Thank you Glenn, much appreciated. Verified that it gave the same (and correct) results as the sed and awk answers.
          – Henry
          Nov 21 '17 at 21:01

















           

          draft saved


          draft discarded















































           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f406109%2fprint-ranges-from-last-occurance-of-a-certain-pattern-to-the-first-occurrence-of%23new-answer', 'question_page');

          );

          Post as a guest













































































          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?