Delete all lines from middle of a line matching a string until the second string match is found

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











up vote
3
down vote

favorite












I am trying to remove the error messages printed into my file.
I have this:



 addr:1122c:1234:
addr:11230:5678:
addr:11223:01Error:abcdef(x, y) = z, value = a
Error:hijklm(v, q) = w, value = b
Error:nopqrst(x, y) = z, value = d
Error:uvwxyz(l, m) = z, value = e
Error:1234(u, t) = z, value = f
Error:567(r, s) = z, value = g
err_total = 9846, err_sub = 0, err_mask = 239
1 Duration: xyz, abc
0 Duration: pqr, def
23:
addr:11238:4567:
addr:1123c:8901:


I need to remove all the error messages upto the next addr appears.
Required output is:



 addr:1122c:1234:
addr:11230:5678:
addr:11223:0123:
addr:11238:4567:
addr:1123c:8901:


I have tried:



sed -i "/bErrorb/d" file_name


But this removes the lines starting from Error and did not remove the line where Error string started from the middle.



I am new to regular expressions, an explaination would be really helpful.



Edit:
I am using sed -i '/Error/,/addr/d' filename
but this removes the whole line and does not give what I am looking for.







share|improve this question

























    up vote
    3
    down vote

    favorite












    I am trying to remove the error messages printed into my file.
    I have this:



     addr:1122c:1234:
    addr:11230:5678:
    addr:11223:01Error:abcdef(x, y) = z, value = a
    Error:hijklm(v, q) = w, value = b
    Error:nopqrst(x, y) = z, value = d
    Error:uvwxyz(l, m) = z, value = e
    Error:1234(u, t) = z, value = f
    Error:567(r, s) = z, value = g
    err_total = 9846, err_sub = 0, err_mask = 239
    1 Duration: xyz, abc
    0 Duration: pqr, def
    23:
    addr:11238:4567:
    addr:1123c:8901:


    I need to remove all the error messages upto the next addr appears.
    Required output is:



     addr:1122c:1234:
    addr:11230:5678:
    addr:11223:0123:
    addr:11238:4567:
    addr:1123c:8901:


    I have tried:



    sed -i "/bErrorb/d" file_name


    But this removes the lines starting from Error and did not remove the line where Error string started from the middle.



    I am new to regular expressions, an explaination would be really helpful.



    Edit:
    I am using sed -i '/Error/,/addr/d' filename
    but this removes the whole line and does not give what I am looking for.







    share|improve this question























      up vote
      3
      down vote

      favorite









      up vote
      3
      down vote

      favorite











      I am trying to remove the error messages printed into my file.
      I have this:



       addr:1122c:1234:
      addr:11230:5678:
      addr:11223:01Error:abcdef(x, y) = z, value = a
      Error:hijklm(v, q) = w, value = b
      Error:nopqrst(x, y) = z, value = d
      Error:uvwxyz(l, m) = z, value = e
      Error:1234(u, t) = z, value = f
      Error:567(r, s) = z, value = g
      err_total = 9846, err_sub = 0, err_mask = 239
      1 Duration: xyz, abc
      0 Duration: pqr, def
      23:
      addr:11238:4567:
      addr:1123c:8901:


      I need to remove all the error messages upto the next addr appears.
      Required output is:



       addr:1122c:1234:
      addr:11230:5678:
      addr:11223:0123:
      addr:11238:4567:
      addr:1123c:8901:


      I have tried:



      sed -i "/bErrorb/d" file_name


      But this removes the lines starting from Error and did not remove the line where Error string started from the middle.



      I am new to regular expressions, an explaination would be really helpful.



      Edit:
      I am using sed -i '/Error/,/addr/d' filename
      but this removes the whole line and does not give what I am looking for.







      share|improve this question













      I am trying to remove the error messages printed into my file.
      I have this:



       addr:1122c:1234:
      addr:11230:5678:
      addr:11223:01Error:abcdef(x, y) = z, value = a
      Error:hijklm(v, q) = w, value = b
      Error:nopqrst(x, y) = z, value = d
      Error:uvwxyz(l, m) = z, value = e
      Error:1234(u, t) = z, value = f
      Error:567(r, s) = z, value = g
      err_total = 9846, err_sub = 0, err_mask = 239
      1 Duration: xyz, abc
      0 Duration: pqr, def
      23:
      addr:11238:4567:
      addr:1123c:8901:


      I need to remove all the error messages upto the next addr appears.
      Required output is:



       addr:1122c:1234:
      addr:11230:5678:
      addr:11223:0123:
      addr:11238:4567:
      addr:1123c:8901:


      I have tried:



      sed -i "/bErrorb/d" file_name


      But this removes the lines starting from Error and did not remove the line where Error string started from the middle.



      I am new to regular expressions, an explaination would be really helpful.



      Edit:
      I am using sed -i '/Error/,/addr/d' filename
      but this removes the whole line and does not give what I am looking for.









      share|improve this question












      share|improve this question




      share|improve this question








      edited Aug 8 at 9:27
























      asked Aug 6 at 9:00









      lost_wanderer

      185




      185




















          3 Answers
          3






          active

          oldest

          votes

















          up vote
          4
          down vote



          accepted










          sed is not really good in Multiline Matching.

          You can trick it to do what you want, but then imo perl is easier to handle.



          Try this:



          perl -pe 'BEGINundef $/;; s/Error.*?(^[0-9]* Duration: [^n]*n)+//smg;'


          Explanation:




          • BEGIN do_something; : Do something once at the beginning


          • undef $/: Ignore line endings


          • s/// Substitute


          • Error.* Match any string beginning with "Error".


          • ? Make the previous match ungreedy, for that it stops at the following match or in this case matching group...


          • ()+ Make a matching group, that needs to be matched at least once (+).


          • ^[0-9]* Duration: [^n]*n: Match the whole line with Duration including.

          (via)






          share|improve this answer























          • Thank you for the answer, works like a charm for the example i gave. However, I had a different example I was working on. I have updated the question, can u please take a look and suggest changes?
            – lost_wanderer
            Aug 6 at 10:28






          • 1




            Updated the answer.
            – RoVo
            Aug 6 at 11:31

















          up vote
          2
          down vote













          Rather than deleting the "Error:" lines, why not extract just the lines you want with:



          grep -E '^ addr:' file_name | sed -e 's/Error:.*//'





          share|improve this answer





















          • I have other lines in the file that does not begin with 'addr' but are needed. Hence I asked for way to remove the unwanted lines.
            – lost_wanderer
            Aug 6 at 13:38






          • 2




            I refuse to track a problem that's revealed a tiny bit at a time. You keep changing requirements, and that's unacceptable.
            – waltinator
            Aug 6 at 13:57










          • Sorry for the miscommunication, my intention was just to remove the unwanted lines and I guess I dint convey it in the best way. Nevertheless, thank you for your answer, upvoted.
            – lost_wanderer
            Aug 7 at 5:41

















          up vote
          1
          down vote













          This will generate the output you have been looking for:



          $ cat file_name | grep -v 
          -e '^Error:'
          -e '^err_total'
          -e '^.*[0-9] Duration:' |
          sed ':a;$!N;s/Error:.*n(.*[0-9]):/1:/;ta;P;D'


          Frist remove all the Error, err_total, and 12345 Duration: stuff. Then search for the Error: ... interrupting your output, remove the newline(n), search for the next occurence of a number (.*[0-9]:) an append it to the current line.






          share|improve this answer























          • Thank you for the answer, works like a charm for the example i gave. However, I had a different example I was working on. I have updated the question, can u please take a look and suggest changes?
            – lost_wanderer
            Aug 6 at 10:31










          Your Answer







          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "89"
          ;
          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: true,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          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%2faskubuntu.com%2fquestions%2f1062808%2fdelete-all-lines-from-middle-of-a-line-matching-a-string-until-the-second-string%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










          sed is not really good in Multiline Matching.

          You can trick it to do what you want, but then imo perl is easier to handle.



          Try this:



          perl -pe 'BEGINundef $/;; s/Error.*?(^[0-9]* Duration: [^n]*n)+//smg;'


          Explanation:




          • BEGIN do_something; : Do something once at the beginning


          • undef $/: Ignore line endings


          • s/// Substitute


          • Error.* Match any string beginning with "Error".


          • ? Make the previous match ungreedy, for that it stops at the following match or in this case matching group...


          • ()+ Make a matching group, that needs to be matched at least once (+).


          • ^[0-9]* Duration: [^n]*n: Match the whole line with Duration including.

          (via)






          share|improve this answer























          • Thank you for the answer, works like a charm for the example i gave. However, I had a different example I was working on. I have updated the question, can u please take a look and suggest changes?
            – lost_wanderer
            Aug 6 at 10:28






          • 1




            Updated the answer.
            – RoVo
            Aug 6 at 11:31














          up vote
          4
          down vote



          accepted










          sed is not really good in Multiline Matching.

          You can trick it to do what you want, but then imo perl is easier to handle.



          Try this:



          perl -pe 'BEGINundef $/;; s/Error.*?(^[0-9]* Duration: [^n]*n)+//smg;'


          Explanation:




          • BEGIN do_something; : Do something once at the beginning


          • undef $/: Ignore line endings


          • s/// Substitute


          • Error.* Match any string beginning with "Error".


          • ? Make the previous match ungreedy, for that it stops at the following match or in this case matching group...


          • ()+ Make a matching group, that needs to be matched at least once (+).


          • ^[0-9]* Duration: [^n]*n: Match the whole line with Duration including.

          (via)






          share|improve this answer























          • Thank you for the answer, works like a charm for the example i gave. However, I had a different example I was working on. I have updated the question, can u please take a look and suggest changes?
            – lost_wanderer
            Aug 6 at 10:28






          • 1




            Updated the answer.
            – RoVo
            Aug 6 at 11:31












          up vote
          4
          down vote



          accepted







          up vote
          4
          down vote



          accepted






          sed is not really good in Multiline Matching.

          You can trick it to do what you want, but then imo perl is easier to handle.



          Try this:



          perl -pe 'BEGINundef $/;; s/Error.*?(^[0-9]* Duration: [^n]*n)+//smg;'


          Explanation:




          • BEGIN do_something; : Do something once at the beginning


          • undef $/: Ignore line endings


          • s/// Substitute


          • Error.* Match any string beginning with "Error".


          • ? Make the previous match ungreedy, for that it stops at the following match or in this case matching group...


          • ()+ Make a matching group, that needs to be matched at least once (+).


          • ^[0-9]* Duration: [^n]*n: Match the whole line with Duration including.

          (via)






          share|improve this answer















          sed is not really good in Multiline Matching.

          You can trick it to do what you want, but then imo perl is easier to handle.



          Try this:



          perl -pe 'BEGINundef $/;; s/Error.*?(^[0-9]* Duration: [^n]*n)+//smg;'


          Explanation:




          • BEGIN do_something; : Do something once at the beginning


          • undef $/: Ignore line endings


          • s/// Substitute


          • Error.* Match any string beginning with "Error".


          • ? Make the previous match ungreedy, for that it stops at the following match or in this case matching group...


          • ()+ Make a matching group, that needs to be matched at least once (+).


          • ^[0-9]* Duration: [^n]*n: Match the whole line with Duration including.

          (via)







          share|improve this answer















          share|improve this answer



          share|improve this answer








          edited Aug 6 at 11:32


























          answered Aug 6 at 9:15









          RoVo

          4,536932




          4,536932











          • Thank you for the answer, works like a charm for the example i gave. However, I had a different example I was working on. I have updated the question, can u please take a look and suggest changes?
            – lost_wanderer
            Aug 6 at 10:28






          • 1




            Updated the answer.
            – RoVo
            Aug 6 at 11:31
















          • Thank you for the answer, works like a charm for the example i gave. However, I had a different example I was working on. I have updated the question, can u please take a look and suggest changes?
            – lost_wanderer
            Aug 6 at 10:28






          • 1




            Updated the answer.
            – RoVo
            Aug 6 at 11:31















          Thank you for the answer, works like a charm for the example i gave. However, I had a different example I was working on. I have updated the question, can u please take a look and suggest changes?
          – lost_wanderer
          Aug 6 at 10:28




          Thank you for the answer, works like a charm for the example i gave. However, I had a different example I was working on. I have updated the question, can u please take a look and suggest changes?
          – lost_wanderer
          Aug 6 at 10:28




          1




          1




          Updated the answer.
          – RoVo
          Aug 6 at 11:31




          Updated the answer.
          – RoVo
          Aug 6 at 11:31












          up vote
          2
          down vote













          Rather than deleting the "Error:" lines, why not extract just the lines you want with:



          grep -E '^ addr:' file_name | sed -e 's/Error:.*//'





          share|improve this answer





















          • I have other lines in the file that does not begin with 'addr' but are needed. Hence I asked for way to remove the unwanted lines.
            – lost_wanderer
            Aug 6 at 13:38






          • 2




            I refuse to track a problem that's revealed a tiny bit at a time. You keep changing requirements, and that's unacceptable.
            – waltinator
            Aug 6 at 13:57










          • Sorry for the miscommunication, my intention was just to remove the unwanted lines and I guess I dint convey it in the best way. Nevertheless, thank you for your answer, upvoted.
            – lost_wanderer
            Aug 7 at 5:41














          up vote
          2
          down vote













          Rather than deleting the "Error:" lines, why not extract just the lines you want with:



          grep -E '^ addr:' file_name | sed -e 's/Error:.*//'





          share|improve this answer





















          • I have other lines in the file that does not begin with 'addr' but are needed. Hence I asked for way to remove the unwanted lines.
            – lost_wanderer
            Aug 6 at 13:38






          • 2




            I refuse to track a problem that's revealed a tiny bit at a time. You keep changing requirements, and that's unacceptable.
            – waltinator
            Aug 6 at 13:57










          • Sorry for the miscommunication, my intention was just to remove the unwanted lines and I guess I dint convey it in the best way. Nevertheless, thank you for your answer, upvoted.
            – lost_wanderer
            Aug 7 at 5:41












          up vote
          2
          down vote










          up vote
          2
          down vote









          Rather than deleting the "Error:" lines, why not extract just the lines you want with:



          grep -E '^ addr:' file_name | sed -e 's/Error:.*//'





          share|improve this answer













          Rather than deleting the "Error:" lines, why not extract just the lines you want with:



          grep -E '^ addr:' file_name | sed -e 's/Error:.*//'






          share|improve this answer













          share|improve this answer



          share|improve this answer











          answered Aug 6 at 13:26









          waltinator

          20.1k73868




          20.1k73868











          • I have other lines in the file that does not begin with 'addr' but are needed. Hence I asked for way to remove the unwanted lines.
            – lost_wanderer
            Aug 6 at 13:38






          • 2




            I refuse to track a problem that's revealed a tiny bit at a time. You keep changing requirements, and that's unacceptable.
            – waltinator
            Aug 6 at 13:57










          • Sorry for the miscommunication, my intention was just to remove the unwanted lines and I guess I dint convey it in the best way. Nevertheless, thank you for your answer, upvoted.
            – lost_wanderer
            Aug 7 at 5:41
















          • I have other lines in the file that does not begin with 'addr' but are needed. Hence I asked for way to remove the unwanted lines.
            – lost_wanderer
            Aug 6 at 13:38






          • 2




            I refuse to track a problem that's revealed a tiny bit at a time. You keep changing requirements, and that's unacceptable.
            – waltinator
            Aug 6 at 13:57










          • Sorry for the miscommunication, my intention was just to remove the unwanted lines and I guess I dint convey it in the best way. Nevertheless, thank you for your answer, upvoted.
            – lost_wanderer
            Aug 7 at 5:41















          I have other lines in the file that does not begin with 'addr' but are needed. Hence I asked for way to remove the unwanted lines.
          – lost_wanderer
          Aug 6 at 13:38




          I have other lines in the file that does not begin with 'addr' but are needed. Hence I asked for way to remove the unwanted lines.
          – lost_wanderer
          Aug 6 at 13:38




          2




          2




          I refuse to track a problem that's revealed a tiny bit at a time. You keep changing requirements, and that's unacceptable.
          – waltinator
          Aug 6 at 13:57




          I refuse to track a problem that's revealed a tiny bit at a time. You keep changing requirements, and that's unacceptable.
          – waltinator
          Aug 6 at 13:57












          Sorry for the miscommunication, my intention was just to remove the unwanted lines and I guess I dint convey it in the best way. Nevertheless, thank you for your answer, upvoted.
          – lost_wanderer
          Aug 7 at 5:41




          Sorry for the miscommunication, my intention was just to remove the unwanted lines and I guess I dint convey it in the best way. Nevertheless, thank you for your answer, upvoted.
          – lost_wanderer
          Aug 7 at 5:41










          up vote
          1
          down vote













          This will generate the output you have been looking for:



          $ cat file_name | grep -v 
          -e '^Error:'
          -e '^err_total'
          -e '^.*[0-9] Duration:' |
          sed ':a;$!N;s/Error:.*n(.*[0-9]):/1:/;ta;P;D'


          Frist remove all the Error, err_total, and 12345 Duration: stuff. Then search for the Error: ... interrupting your output, remove the newline(n), search for the next occurence of a number (.*[0-9]:) an append it to the current line.






          share|improve this answer























          • Thank you for the answer, works like a charm for the example i gave. However, I had a different example I was working on. I have updated the question, can u please take a look and suggest changes?
            – lost_wanderer
            Aug 6 at 10:31














          up vote
          1
          down vote













          This will generate the output you have been looking for:



          $ cat file_name | grep -v 
          -e '^Error:'
          -e '^err_total'
          -e '^.*[0-9] Duration:' |
          sed ':a;$!N;s/Error:.*n(.*[0-9]):/1:/;ta;P;D'


          Frist remove all the Error, err_total, and 12345 Duration: stuff. Then search for the Error: ... interrupting your output, remove the newline(n), search for the next occurence of a number (.*[0-9]:) an append it to the current line.






          share|improve this answer























          • Thank you for the answer, works like a charm for the example i gave. However, I had a different example I was working on. I have updated the question, can u please take a look and suggest changes?
            – lost_wanderer
            Aug 6 at 10:31












          up vote
          1
          down vote










          up vote
          1
          down vote









          This will generate the output you have been looking for:



          $ cat file_name | grep -v 
          -e '^Error:'
          -e '^err_total'
          -e '^.*[0-9] Duration:' |
          sed ':a;$!N;s/Error:.*n(.*[0-9]):/1:/;ta;P;D'


          Frist remove all the Error, err_total, and 12345 Duration: stuff. Then search for the Error: ... interrupting your output, remove the newline(n), search for the next occurence of a number (.*[0-9]:) an append it to the current line.






          share|improve this answer















          This will generate the output you have been looking for:



          $ cat file_name | grep -v 
          -e '^Error:'
          -e '^err_total'
          -e '^.*[0-9] Duration:' |
          sed ':a;$!N;s/Error:.*n(.*[0-9]):/1:/;ta;P;D'


          Frist remove all the Error, err_total, and 12345 Duration: stuff. Then search for the Error: ... interrupting your output, remove the newline(n), search for the next occurence of a number (.*[0-9]:) an append it to the current line.







          share|improve this answer















          share|improve this answer



          share|improve this answer








          edited Aug 6 at 10:24


























          answered Aug 6 at 9:24









          Simon Sudler

          892111




          892111











          • Thank you for the answer, works like a charm for the example i gave. However, I had a different example I was working on. I have updated the question, can u please take a look and suggest changes?
            – lost_wanderer
            Aug 6 at 10:31
















          • Thank you for the answer, works like a charm for the example i gave. However, I had a different example I was working on. I have updated the question, can u please take a look and suggest changes?
            – lost_wanderer
            Aug 6 at 10:31















          Thank you for the answer, works like a charm for the example i gave. However, I had a different example I was working on. I have updated the question, can u please take a look and suggest changes?
          – lost_wanderer
          Aug 6 at 10:31




          Thank you for the answer, works like a charm for the example i gave. However, I had a different example I was working on. I have updated the question, can u please take a look and suggest changes?
          – lost_wanderer
          Aug 6 at 10:31












           

          draft saved


          draft discarded


























           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f1062808%2fdelete-all-lines-from-middle-of-a-line-matching-a-string-until-the-second-string%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

          Is the Concept of Multiple Fantasy Races Scientifically Flawed? [closed]

          Confectionery