Match patternA and print it only when patternB is matched including the following line

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











up vote
4
down vote

favorite












I am looking to get all the lines which have the word 'search_string' + the line after it + the line matching 'mod' before it.

I tried:



grep -n 'mod|search_string' ip | grep --before 1 search_string> inter 
grep -n --after 1 search_string ip >> inter
sort -t':' -k1,1n -u inter -o op


Is there a better way?



File:



mod start1 
some lines
mod start2
other lines
mod start3
many other lines
search_string yada yada
hello
many other lines
search_string yada yada
bye
mod start4
search_string baba baba
this too
mod start5


Expected output :



mod start3 
search_string yada yada
hello
search_string yada yada
bye
mod start4
search_string baba baba
this too






share|improve this question






















  • In your example you have search_string and search string. Are they both valid?
    – Kamil Maciorowski
    Aug 25 at 19:28










  • The output of the commands you show do not match the expected output you present. Which is correct ?
    – Isaac
    Aug 25 at 19:34










  • It was a typo. Corrected it to show search_string. The final results should match the expected results. I was only trying to show the convoluted steps I was thinking of and not getting proper results.
    – romi
    Aug 25 at 20:27















up vote
4
down vote

favorite












I am looking to get all the lines which have the word 'search_string' + the line after it + the line matching 'mod' before it.

I tried:



grep -n 'mod|search_string' ip | grep --before 1 search_string> inter 
grep -n --after 1 search_string ip >> inter
sort -t':' -k1,1n -u inter -o op


Is there a better way?



File:



mod start1 
some lines
mod start2
other lines
mod start3
many other lines
search_string yada yada
hello
many other lines
search_string yada yada
bye
mod start4
search_string baba baba
this too
mod start5


Expected output :



mod start3 
search_string yada yada
hello
search_string yada yada
bye
mod start4
search_string baba baba
this too






share|improve this question






















  • In your example you have search_string and search string. Are they both valid?
    – Kamil Maciorowski
    Aug 25 at 19:28










  • The output of the commands you show do not match the expected output you present. Which is correct ?
    – Isaac
    Aug 25 at 19:34










  • It was a typo. Corrected it to show search_string. The final results should match the expected results. I was only trying to show the convoluted steps I was thinking of and not getting proper results.
    – romi
    Aug 25 at 20:27













up vote
4
down vote

favorite









up vote
4
down vote

favorite











I am looking to get all the lines which have the word 'search_string' + the line after it + the line matching 'mod' before it.

I tried:



grep -n 'mod|search_string' ip | grep --before 1 search_string> inter 
grep -n --after 1 search_string ip >> inter
sort -t':' -k1,1n -u inter -o op


Is there a better way?



File:



mod start1 
some lines
mod start2
other lines
mod start3
many other lines
search_string yada yada
hello
many other lines
search_string yada yada
bye
mod start4
search_string baba baba
this too
mod start5


Expected output :



mod start3 
search_string yada yada
hello
search_string yada yada
bye
mod start4
search_string baba baba
this too






share|improve this question














I am looking to get all the lines which have the word 'search_string' + the line after it + the line matching 'mod' before it.

I tried:



grep -n 'mod|search_string' ip | grep --before 1 search_string> inter 
grep -n --after 1 search_string ip >> inter
sort -t':' -k1,1n -u inter -o op


Is there a better way?



File:



mod start1 
some lines
mod start2
other lines
mod start3
many other lines
search_string yada yada
hello
many other lines
search_string yada yada
bye
mod start4
search_string baba baba
this too
mod start5


Expected output :



mod start3 
search_string yada yada
hello
search_string yada yada
bye
mod start4
search_string baba baba
this too








share|improve this question













share|improve this question




share|improve this question








edited Aug 26 at 7:52









αғsнιη

15.5k92563




15.5k92563










asked Aug 25 at 18:46









romi

235




235











  • In your example you have search_string and search string. Are they both valid?
    – Kamil Maciorowski
    Aug 25 at 19:28










  • The output of the commands you show do not match the expected output you present. Which is correct ?
    – Isaac
    Aug 25 at 19:34










  • It was a typo. Corrected it to show search_string. The final results should match the expected results. I was only trying to show the convoluted steps I was thinking of and not getting proper results.
    – romi
    Aug 25 at 20:27

















  • In your example you have search_string and search string. Are they both valid?
    – Kamil Maciorowski
    Aug 25 at 19:28










  • The output of the commands you show do not match the expected output you present. Which is correct ?
    – Isaac
    Aug 25 at 19:34










  • It was a typo. Corrected it to show search_string. The final results should match the expected results. I was only trying to show the convoluted steps I was thinking of and not getting proper results.
    – romi
    Aug 25 at 20:27
















In your example you have search_string and search string. Are they both valid?
– Kamil Maciorowski
Aug 25 at 19:28




In your example you have search_string and search string. Are they both valid?
– Kamil Maciorowski
Aug 25 at 19:28












The output of the commands you show do not match the expected output you present. Which is correct ?
– Isaac
Aug 25 at 19:34




The output of the commands you show do not match the expected output you present. Which is correct ?
– Isaac
Aug 25 at 19:34












It was a typo. Corrected it to show search_string. The final results should match the expected results. I was only trying to show the convoluted steps I was thinking of and not getting proper results.
– romi
Aug 25 at 20:27





It was a typo. Corrected it to show search_string. The final results should match the expected results. I was only trying to show the convoluted steps I was thinking of and not getting proper results.
– romi
Aug 25 at 20:27











3 Answers
3






active

oldest

votes

















up vote
4
down vote



accepted










awk '
$0 ~ /mod/ md=$0
$0 ~ /search_string/ if(md!="") print md ; md="" ; print; getline; print
'


Explanation:



  • A line containing mod is saved as md.

  • A line containing search_string triggers printing the previously saved md, the line itself and the next line.


  • if(md!="") and md="" are there to make sure you don't get duplicated mod lines when there are many search_string-s under a single mod (mod start3 in your example).

Note:



  • A line containing both mod and search_string will break this logic.





share|improve this answer






















  • Kamil, Thankyou! This works for me!
    – romi
    Aug 26 at 7:31

















up vote
2
down vote













Your file contains "carriage return" characters. It is better to remove them in Unix. To print what the sequence of commands you posted print (with carriage returns removed), try:



awk 'gsub(/r/,"")
/mod/ a = $0
/search_string/ if(a!="")print(a);a=""
print;getline;print

' infile


Or as a one-liner:



$ awk 'gsub(/r/,"")/mod/a=$0/search_string/if(a!="")print(a);a=""print;getline;print' infile

mod start3
search_string yada yada
hello
search_string yada yada
bye
mod start4
search_string baba baba
this too



As it is possible to use a multi character record separator in (GNU) awk we can set the record separator to mod and print only records that contain search_string. The printf is required to reconstruct the original record.



To print what you posted as "Expected output" try:



awk '/search_string/printf("mod%s", $0)' RS=mod infile





share|improve this answer





























    up vote
    0
    down vote













    If you want this in a Python script:



    # Read file into memory.
    with open('myfile.txt') as f:
    lines = [line.rstrip() for line in f]

    # Loops through lines backwards, looking for string and optionally mod.
    output_lines = list()
    find_mod = False
    for i, line in enumerate(lines[::-1]):
    if 'search_string' in line:
    output_lines.append(lines[::-1][i-1])
    output_lines.append(lines[::-1][i])
    find_mod = True
    elif find_mod and 'mod' in line:
    output_lines.append(lines[::-1][i])
    find_mod=False

    print("n".join(output_lines[::-1]))





    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',
      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%2f464824%2fmatch-patterna-and-print-it-only-when-patternb-is-matched-including-the-followin%23new-answer', 'question_page');

      );

      Post as a guest






























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      4
      down vote



      accepted










      awk '
      $0 ~ /mod/ md=$0
      $0 ~ /search_string/ if(md!="") print md ; md="" ; print; getline; print
      '


      Explanation:



      • A line containing mod is saved as md.

      • A line containing search_string triggers printing the previously saved md, the line itself and the next line.


      • if(md!="") and md="" are there to make sure you don't get duplicated mod lines when there are many search_string-s under a single mod (mod start3 in your example).

      Note:



      • A line containing both mod and search_string will break this logic.





      share|improve this answer






















      • Kamil, Thankyou! This works for me!
        – romi
        Aug 26 at 7:31














      up vote
      4
      down vote



      accepted










      awk '
      $0 ~ /mod/ md=$0
      $0 ~ /search_string/ if(md!="") print md ; md="" ; print; getline; print
      '


      Explanation:



      • A line containing mod is saved as md.

      • A line containing search_string triggers printing the previously saved md, the line itself and the next line.


      • if(md!="") and md="" are there to make sure you don't get duplicated mod lines when there are many search_string-s under a single mod (mod start3 in your example).

      Note:



      • A line containing both mod and search_string will break this logic.





      share|improve this answer






















      • Kamil, Thankyou! This works for me!
        – romi
        Aug 26 at 7:31












      up vote
      4
      down vote



      accepted







      up vote
      4
      down vote



      accepted






      awk '
      $0 ~ /mod/ md=$0
      $0 ~ /search_string/ if(md!="") print md ; md="" ; print; getline; print
      '


      Explanation:



      • A line containing mod is saved as md.

      • A line containing search_string triggers printing the previously saved md, the line itself and the next line.


      • if(md!="") and md="" are there to make sure you don't get duplicated mod lines when there are many search_string-s under a single mod (mod start3 in your example).

      Note:



      • A line containing both mod and search_string will break this logic.





      share|improve this answer














      awk '
      $0 ~ /mod/ md=$0
      $0 ~ /search_string/ if(md!="") print md ; md="" ; print; getline; print
      '


      Explanation:



      • A line containing mod is saved as md.

      • A line containing search_string triggers printing the previously saved md, the line itself and the next line.


      • if(md!="") and md="" are there to make sure you don't get duplicated mod lines when there are many search_string-s under a single mod (mod start3 in your example).

      Note:



      • A line containing both mod and search_string will break this logic.






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Aug 26 at 13:34

























      answered Aug 25 at 19:27









      Kamil Maciorowski

      1,0791523




      1,0791523











      • Kamil, Thankyou! This works for me!
        – romi
        Aug 26 at 7:31
















      • Kamil, Thankyou! This works for me!
        – romi
        Aug 26 at 7:31















      Kamil, Thankyou! This works for me!
      – romi
      Aug 26 at 7:31




      Kamil, Thankyou! This works for me!
      – romi
      Aug 26 at 7:31












      up vote
      2
      down vote













      Your file contains "carriage return" characters. It is better to remove them in Unix. To print what the sequence of commands you posted print (with carriage returns removed), try:



      awk 'gsub(/r/,"")
      /mod/ a = $0
      /search_string/ if(a!="")print(a);a=""
      print;getline;print

      ' infile


      Or as a one-liner:



      $ awk 'gsub(/r/,"")/mod/a=$0/search_string/if(a!="")print(a);a=""print;getline;print' infile

      mod start3
      search_string yada yada
      hello
      search_string yada yada
      bye
      mod start4
      search_string baba baba
      this too



      As it is possible to use a multi character record separator in (GNU) awk we can set the record separator to mod and print only records that contain search_string. The printf is required to reconstruct the original record.



      To print what you posted as "Expected output" try:



      awk '/search_string/printf("mod%s", $0)' RS=mod infile





      share|improve this answer


























        up vote
        2
        down vote













        Your file contains "carriage return" characters. It is better to remove them in Unix. To print what the sequence of commands you posted print (with carriage returns removed), try:



        awk 'gsub(/r/,"")
        /mod/ a = $0
        /search_string/ if(a!="")print(a);a=""
        print;getline;print

        ' infile


        Or as a one-liner:



        $ awk 'gsub(/r/,"")/mod/a=$0/search_string/if(a!="")print(a);a=""print;getline;print' infile

        mod start3
        search_string yada yada
        hello
        search_string yada yada
        bye
        mod start4
        search_string baba baba
        this too



        As it is possible to use a multi character record separator in (GNU) awk we can set the record separator to mod and print only records that contain search_string. The printf is required to reconstruct the original record.



        To print what you posted as "Expected output" try:



        awk '/search_string/printf("mod%s", $0)' RS=mod infile





        share|improve this answer
























          up vote
          2
          down vote










          up vote
          2
          down vote









          Your file contains "carriage return" characters. It is better to remove them in Unix. To print what the sequence of commands you posted print (with carriage returns removed), try:



          awk 'gsub(/r/,"")
          /mod/ a = $0
          /search_string/ if(a!="")print(a);a=""
          print;getline;print

          ' infile


          Or as a one-liner:



          $ awk 'gsub(/r/,"")/mod/a=$0/search_string/if(a!="")print(a);a=""print;getline;print' infile

          mod start3
          search_string yada yada
          hello
          search_string yada yada
          bye
          mod start4
          search_string baba baba
          this too



          As it is possible to use a multi character record separator in (GNU) awk we can set the record separator to mod and print only records that contain search_string. The printf is required to reconstruct the original record.



          To print what you posted as "Expected output" try:



          awk '/search_string/printf("mod%s", $0)' RS=mod infile





          share|improve this answer














          Your file contains "carriage return" characters. It is better to remove them in Unix. To print what the sequence of commands you posted print (with carriage returns removed), try:



          awk 'gsub(/r/,"")
          /mod/ a = $0
          /search_string/ if(a!="")print(a);a=""
          print;getline;print

          ' infile


          Or as a one-liner:



          $ awk 'gsub(/r/,"")/mod/a=$0/search_string/if(a!="")print(a);a=""print;getline;print' infile

          mod start3
          search_string yada yada
          hello
          search_string yada yada
          bye
          mod start4
          search_string baba baba
          this too



          As it is possible to use a multi character record separator in (GNU) awk we can set the record separator to mod and print only records that contain search_string. The printf is required to reconstruct the original record.



          To print what you posted as "Expected output" try:



          awk '/search_string/printf("mod%s", $0)' RS=mod infile






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Aug 25 at 20:33

























          answered Aug 25 at 19:25









          Isaac

          6,8001834




          6,8001834




















              up vote
              0
              down vote













              If you want this in a Python script:



              # Read file into memory.
              with open('myfile.txt') as f:
              lines = [line.rstrip() for line in f]

              # Loops through lines backwards, looking for string and optionally mod.
              output_lines = list()
              find_mod = False
              for i, line in enumerate(lines[::-1]):
              if 'search_string' in line:
              output_lines.append(lines[::-1][i-1])
              output_lines.append(lines[::-1][i])
              find_mod = True
              elif find_mod and 'mod' in line:
              output_lines.append(lines[::-1][i])
              find_mod=False

              print("n".join(output_lines[::-1]))





              share|improve this answer
























                up vote
                0
                down vote













                If you want this in a Python script:



                # Read file into memory.
                with open('myfile.txt') as f:
                lines = [line.rstrip() for line in f]

                # Loops through lines backwards, looking for string and optionally mod.
                output_lines = list()
                find_mod = False
                for i, line in enumerate(lines[::-1]):
                if 'search_string' in line:
                output_lines.append(lines[::-1][i-1])
                output_lines.append(lines[::-1][i])
                find_mod = True
                elif find_mod and 'mod' in line:
                output_lines.append(lines[::-1][i])
                find_mod=False

                print("n".join(output_lines[::-1]))





                share|improve this answer






















                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  If you want this in a Python script:



                  # Read file into memory.
                  with open('myfile.txt') as f:
                  lines = [line.rstrip() for line in f]

                  # Loops through lines backwards, looking for string and optionally mod.
                  output_lines = list()
                  find_mod = False
                  for i, line in enumerate(lines[::-1]):
                  if 'search_string' in line:
                  output_lines.append(lines[::-1][i-1])
                  output_lines.append(lines[::-1][i])
                  find_mod = True
                  elif find_mod and 'mod' in line:
                  output_lines.append(lines[::-1][i])
                  find_mod=False

                  print("n".join(output_lines[::-1]))





                  share|improve this answer












                  If you want this in a Python script:



                  # Read file into memory.
                  with open('myfile.txt') as f:
                  lines = [line.rstrip() for line in f]

                  # Loops through lines backwards, looking for string and optionally mod.
                  output_lines = list()
                  find_mod = False
                  for i, line in enumerate(lines[::-1]):
                  if 'search_string' in line:
                  output_lines.append(lines[::-1][i-1])
                  output_lines.append(lines[::-1][i])
                  find_mod = True
                  elif find_mod and 'mod' in line:
                  output_lines.append(lines[::-1][i])
                  find_mod=False

                  print("n".join(output_lines[::-1]))






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Aug 26 at 2:36









                  user1717828

                  1,59611125




                  1,59611125



























                       

                      draft saved


                      draft discarded















































                       


                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f464824%2fmatch-patterna-and-print-it-only-when-patternb-is-matched-including-the-followin%23new-answer', 'question_page');

                      );

                      Post as a guest













































































                      Comments

                      Popular posts from this blog

                      Long meetings (6-7 hours a day): Being “babysat” by supervisor

                      What does second last employer means? [closed]

                      One-line joke