sed: extract lines until unmatched pattern











up vote
2
down vote

favorite












I am trying to extract lines from a file where the end string is different from the begin string



I have the following input file in format:



<item_id>6</item_id>
<info1>abc</info1>
<info2>123</info2>
<item_id>6</item_id>
<info1>def</info1>
<info2>456</info2>
<item_id>6</item_id>
<info1>ghi</info1>
<info2>789</info2>
<item_id>9</item_id>
<info1>jkl</info1>
<info2>012</info2>
<item_id>9</item_id>
<info1>mno</info1>
<info2>345</info2>


I want to extract from "6" until "9" (9 being a random number)



Begin is <item_id>6<item_id>



End is <item_id>X<item_id> X being anything but 6



Expected result:



<item_id>6</item_id>
<info1>abc</info1>
<info2>123</info2>
<item_id>6</item_id>
<info1>def</info1>
<info2>456</info2>
<item_id>6</item_id>
<info1>ghi</info1>
<info2>789</info2>


I tried:



sed -n "/<item_id>6</item_id>/,/<item_id>!6</item_id>/p" input.file > output.6
sed -n "/<item_id>6</item_id>/,/<item_id>!6</item_id>/p" input.file > output.6
sed -n "/<item_id>6</item_id>/,/<item_id>{!6}</item_id>/p" input.file > output.6
sed -n "/<item_id>6</item_id>/,/<item_id>(6)@!.</item_id>/p" input.file > output.6
sed -n "/<item_id>6</item_id>/,/<item_id>! 6</item_id>/p" input.file > output.6









share|improve this question




























    up vote
    2
    down vote

    favorite












    I am trying to extract lines from a file where the end string is different from the begin string



    I have the following input file in format:



    <item_id>6</item_id>
    <info1>abc</info1>
    <info2>123</info2>
    <item_id>6</item_id>
    <info1>def</info1>
    <info2>456</info2>
    <item_id>6</item_id>
    <info1>ghi</info1>
    <info2>789</info2>
    <item_id>9</item_id>
    <info1>jkl</info1>
    <info2>012</info2>
    <item_id>9</item_id>
    <info1>mno</info1>
    <info2>345</info2>


    I want to extract from "6" until "9" (9 being a random number)



    Begin is <item_id>6<item_id>



    End is <item_id>X<item_id> X being anything but 6



    Expected result:



    <item_id>6</item_id>
    <info1>abc</info1>
    <info2>123</info2>
    <item_id>6</item_id>
    <info1>def</info1>
    <info2>456</info2>
    <item_id>6</item_id>
    <info1>ghi</info1>
    <info2>789</info2>


    I tried:



    sed -n "/<item_id>6</item_id>/,/<item_id>!6</item_id>/p" input.file > output.6
    sed -n "/<item_id>6</item_id>/,/<item_id>!6</item_id>/p" input.file > output.6
    sed -n "/<item_id>6</item_id>/,/<item_id>{!6}</item_id>/p" input.file > output.6
    sed -n "/<item_id>6</item_id>/,/<item_id>(6)@!.</item_id>/p" input.file > output.6
    sed -n "/<item_id>6</item_id>/,/<item_id>! 6</item_id>/p" input.file > output.6









    share|improve this question


























      up vote
      2
      down vote

      favorite









      up vote
      2
      down vote

      favorite











      I am trying to extract lines from a file where the end string is different from the begin string



      I have the following input file in format:



      <item_id>6</item_id>
      <info1>abc</info1>
      <info2>123</info2>
      <item_id>6</item_id>
      <info1>def</info1>
      <info2>456</info2>
      <item_id>6</item_id>
      <info1>ghi</info1>
      <info2>789</info2>
      <item_id>9</item_id>
      <info1>jkl</info1>
      <info2>012</info2>
      <item_id>9</item_id>
      <info1>mno</info1>
      <info2>345</info2>


      I want to extract from "6" until "9" (9 being a random number)



      Begin is <item_id>6<item_id>



      End is <item_id>X<item_id> X being anything but 6



      Expected result:



      <item_id>6</item_id>
      <info1>abc</info1>
      <info2>123</info2>
      <item_id>6</item_id>
      <info1>def</info1>
      <info2>456</info2>
      <item_id>6</item_id>
      <info1>ghi</info1>
      <info2>789</info2>


      I tried:



      sed -n "/<item_id>6</item_id>/,/<item_id>!6</item_id>/p" input.file > output.6
      sed -n "/<item_id>6</item_id>/,/<item_id>!6</item_id>/p" input.file > output.6
      sed -n "/<item_id>6</item_id>/,/<item_id>{!6}</item_id>/p" input.file > output.6
      sed -n "/<item_id>6</item_id>/,/<item_id>(6)@!.</item_id>/p" input.file > output.6
      sed -n "/<item_id>6</item_id>/,/<item_id>! 6</item_id>/p" input.file > output.6









      share|improve this question















      I am trying to extract lines from a file where the end string is different from the begin string



      I have the following input file in format:



      <item_id>6</item_id>
      <info1>abc</info1>
      <info2>123</info2>
      <item_id>6</item_id>
      <info1>def</info1>
      <info2>456</info2>
      <item_id>6</item_id>
      <info1>ghi</info1>
      <info2>789</info2>
      <item_id>9</item_id>
      <info1>jkl</info1>
      <info2>012</info2>
      <item_id>9</item_id>
      <info1>mno</info1>
      <info2>345</info2>


      I want to extract from "6" until "9" (9 being a random number)



      Begin is <item_id>6<item_id>



      End is <item_id>X<item_id> X being anything but 6



      Expected result:



      <item_id>6</item_id>
      <info1>abc</info1>
      <info2>123</info2>
      <item_id>6</item_id>
      <info1>def</info1>
      <info2>456</info2>
      <item_id>6</item_id>
      <info1>ghi</info1>
      <info2>789</info2>


      I tried:



      sed -n "/<item_id>6</item_id>/,/<item_id>!6</item_id>/p" input.file > output.6
      sed -n "/<item_id>6</item_id>/,/<item_id>!6</item_id>/p" input.file > output.6
      sed -n "/<item_id>6</item_id>/,/<item_id>{!6}</item_id>/p" input.file > output.6
      sed -n "/<item_id>6</item_id>/,/<item_id>(6)@!.</item_id>/p" input.file > output.6
      sed -n "/<item_id>6</item_id>/,/<item_id>! 6</item_id>/p" input.file > output.6






      text-processing sed xml






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 11 at 11:48









      Isaac

      9,69211445




      9,69211445










      asked Nov 10 at 20:05









      xavi

      133




      133






















          2 Answers
          2






          active

          oldest

          votes

















          up vote
          3
          down vote



          accepted










          Maybe this GNU sed script will work for you:



          sed '/<item_id>6</item_id>/{:1;n;/<item_id>[^6]</item_id>/{Q};b1};d' file


          Keep deleting d lines until a 6 line is found, then keep in the internal loop b1 printing each line until a not 6 ([^6]) line is found, at which time the script is Quit.



          Understand that this works only for one character numbers (the 6 or the 9).





          It gets quite messy to get it to work with any number (GNU):



          sed -e 'h;s,<item_id>([0-9]*)</item_id>,1,;/^6$/!d;/^6$/{g;:1;h;s,<item_id>([0-9]*)</item_id>,1,;t2;:3;g;n;b1};d;b;:2;/^6$/!Q;b3' file


          Using a couple of vars makes it a bit better, but not that much



          reg='<item_id>([0-9]*)</item_id>'
          item='6'

          sed -e "h;s,$reg,1,;/^$item$/!d;/^$item$/{g;:1;h;s,$reg,1,;t2;:3;g;n;b1};d;b;:2;/^$item$/!Q;b3" file


          And a POSIXfyed one looks like gibberish:



          sed -ne 'h;s,<item_id>([0-9]*)</item_id>,1,;/^6$/!d;/^6$/{g;:1;h;s,<item_id>([0-9]*)</item_id>,1,;t2;:3;g;p;n;b1;};d;b;:2;/^6$/!q;b3' file


          Only this extended code might(?) be more readable:



          reg='<item_id>([0-9]*)</item_id>'
          item='6'

          sed -ne 'h; # hold copy of line being processed.
          s,'"$reg"',1,; # extract included number.
          /^'"$item"'$/!d; # Not the correct number?: get next line.
          /^'"$item"'$/{
          g; # restore line from hold buffer.
          :1
          h; # store successive lines in hold buffer.
          s,'"$reg"',1,; # extract the number (again).
          t2
          :3
          g; # restore the line back from hold buffer.
          p; # print the line.
          n; # go to process next line.
          b1
          }; # end of loop.
          d; # avoid printing this last line.
          q; # quit the sed script.
          :2
          /^'"$item"'$/!q; # Test if the number is the one selected.
          b3
          ' file


          Maybe you should use some other language or tool.






          share|improve this answer























          • This will not break out of the loop if the next item has two or three digits, only works with one digit items...
            – Filipe Brandenburger
            Nov 10 at 21:01










          • that's great. almost there. it does not work for a string <item_id>12 until <item_id>15 for example :(.. i tried a few things but cant get it
            – xavi
            Nov 10 at 21:04












          • @FilipeBrandenburger Yes, that is what I said one character numbers. Anyway, a more flexible (but hard to read) solution added.
            – Isaac
            Nov 11 at 6:32










          • thanks! it makes it complicated indeed but this works perfectly. thanks again.
            – xavi
            Nov 11 at 9:52


















          up vote
          5
          down vote













          Assuming this is a well-formed XML document, the following uses XMLStarlet to pick out the info_id nodes whose values are 6, and then the immediately following sibling info1 and info2 nodes:



          $ xmlstarlet sel -t -m '//item_id[. = 6]' 
          -c . -nl
          -c './following-sibling::info1[1]' -nl
          -c './following-sibling::info2[1]' -nl file.xml
          <item_id>6</item_id>
          <info1>abc</info1>
          <info2>123</info2>
          <item_id>6</item_id>
          <info1>def</info1>
          <info2>456</info2>
          <item_id>6</item_id>
          <info1>ghi</info1>
          <info2>789</info2>


          Alternatively, to ignore what the following nodes are called:



          xmlstarlet sel -t -m '//item_id[. = 6]' 
          -c . -nl
          -c './following-sibling::*[1]' -nl
          -c './following-sibling::*[2]' -nl file.xml





          share|improve this answer























          • that does the trick! thanks
            – xavi
            Nov 10 at 22:16











          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: 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%2f480998%2fsed-extract-lines-until-unmatched-pattern%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          3
          down vote



          accepted










          Maybe this GNU sed script will work for you:



          sed '/<item_id>6</item_id>/{:1;n;/<item_id>[^6]</item_id>/{Q};b1};d' file


          Keep deleting d lines until a 6 line is found, then keep in the internal loop b1 printing each line until a not 6 ([^6]) line is found, at which time the script is Quit.



          Understand that this works only for one character numbers (the 6 or the 9).





          It gets quite messy to get it to work with any number (GNU):



          sed -e 'h;s,<item_id>([0-9]*)</item_id>,1,;/^6$/!d;/^6$/{g;:1;h;s,<item_id>([0-9]*)</item_id>,1,;t2;:3;g;n;b1};d;b;:2;/^6$/!Q;b3' file


          Using a couple of vars makes it a bit better, but not that much



          reg='<item_id>([0-9]*)</item_id>'
          item='6'

          sed -e "h;s,$reg,1,;/^$item$/!d;/^$item$/{g;:1;h;s,$reg,1,;t2;:3;g;n;b1};d;b;:2;/^$item$/!Q;b3" file


          And a POSIXfyed one looks like gibberish:



          sed -ne 'h;s,<item_id>([0-9]*)</item_id>,1,;/^6$/!d;/^6$/{g;:1;h;s,<item_id>([0-9]*)</item_id>,1,;t2;:3;g;p;n;b1;};d;b;:2;/^6$/!q;b3' file


          Only this extended code might(?) be more readable:



          reg='<item_id>([0-9]*)</item_id>'
          item='6'

          sed -ne 'h; # hold copy of line being processed.
          s,'"$reg"',1,; # extract included number.
          /^'"$item"'$/!d; # Not the correct number?: get next line.
          /^'"$item"'$/{
          g; # restore line from hold buffer.
          :1
          h; # store successive lines in hold buffer.
          s,'"$reg"',1,; # extract the number (again).
          t2
          :3
          g; # restore the line back from hold buffer.
          p; # print the line.
          n; # go to process next line.
          b1
          }; # end of loop.
          d; # avoid printing this last line.
          q; # quit the sed script.
          :2
          /^'"$item"'$/!q; # Test if the number is the one selected.
          b3
          ' file


          Maybe you should use some other language or tool.






          share|improve this answer























          • This will not break out of the loop if the next item has two or three digits, only works with one digit items...
            – Filipe Brandenburger
            Nov 10 at 21:01










          • that's great. almost there. it does not work for a string <item_id>12 until <item_id>15 for example :(.. i tried a few things but cant get it
            – xavi
            Nov 10 at 21:04












          • @FilipeBrandenburger Yes, that is what I said one character numbers. Anyway, a more flexible (but hard to read) solution added.
            – Isaac
            Nov 11 at 6:32










          • thanks! it makes it complicated indeed but this works perfectly. thanks again.
            – xavi
            Nov 11 at 9:52















          up vote
          3
          down vote



          accepted










          Maybe this GNU sed script will work for you:



          sed '/<item_id>6</item_id>/{:1;n;/<item_id>[^6]</item_id>/{Q};b1};d' file


          Keep deleting d lines until a 6 line is found, then keep in the internal loop b1 printing each line until a not 6 ([^6]) line is found, at which time the script is Quit.



          Understand that this works only for one character numbers (the 6 or the 9).





          It gets quite messy to get it to work with any number (GNU):



          sed -e 'h;s,<item_id>([0-9]*)</item_id>,1,;/^6$/!d;/^6$/{g;:1;h;s,<item_id>([0-9]*)</item_id>,1,;t2;:3;g;n;b1};d;b;:2;/^6$/!Q;b3' file


          Using a couple of vars makes it a bit better, but not that much



          reg='<item_id>([0-9]*)</item_id>'
          item='6'

          sed -e "h;s,$reg,1,;/^$item$/!d;/^$item$/{g;:1;h;s,$reg,1,;t2;:3;g;n;b1};d;b;:2;/^$item$/!Q;b3" file


          And a POSIXfyed one looks like gibberish:



          sed -ne 'h;s,<item_id>([0-9]*)</item_id>,1,;/^6$/!d;/^6$/{g;:1;h;s,<item_id>([0-9]*)</item_id>,1,;t2;:3;g;p;n;b1;};d;b;:2;/^6$/!q;b3' file


          Only this extended code might(?) be more readable:



          reg='<item_id>([0-9]*)</item_id>'
          item='6'

          sed -ne 'h; # hold copy of line being processed.
          s,'"$reg"',1,; # extract included number.
          /^'"$item"'$/!d; # Not the correct number?: get next line.
          /^'"$item"'$/{
          g; # restore line from hold buffer.
          :1
          h; # store successive lines in hold buffer.
          s,'"$reg"',1,; # extract the number (again).
          t2
          :3
          g; # restore the line back from hold buffer.
          p; # print the line.
          n; # go to process next line.
          b1
          }; # end of loop.
          d; # avoid printing this last line.
          q; # quit the sed script.
          :2
          /^'"$item"'$/!q; # Test if the number is the one selected.
          b3
          ' file


          Maybe you should use some other language or tool.






          share|improve this answer























          • This will not break out of the loop if the next item has two or three digits, only works with one digit items...
            – Filipe Brandenburger
            Nov 10 at 21:01










          • that's great. almost there. it does not work for a string <item_id>12 until <item_id>15 for example :(.. i tried a few things but cant get it
            – xavi
            Nov 10 at 21:04












          • @FilipeBrandenburger Yes, that is what I said one character numbers. Anyway, a more flexible (but hard to read) solution added.
            – Isaac
            Nov 11 at 6:32










          • thanks! it makes it complicated indeed but this works perfectly. thanks again.
            – xavi
            Nov 11 at 9:52













          up vote
          3
          down vote



          accepted







          up vote
          3
          down vote



          accepted






          Maybe this GNU sed script will work for you:



          sed '/<item_id>6</item_id>/{:1;n;/<item_id>[^6]</item_id>/{Q};b1};d' file


          Keep deleting d lines until a 6 line is found, then keep in the internal loop b1 printing each line until a not 6 ([^6]) line is found, at which time the script is Quit.



          Understand that this works only for one character numbers (the 6 or the 9).





          It gets quite messy to get it to work with any number (GNU):



          sed -e 'h;s,<item_id>([0-9]*)</item_id>,1,;/^6$/!d;/^6$/{g;:1;h;s,<item_id>([0-9]*)</item_id>,1,;t2;:3;g;n;b1};d;b;:2;/^6$/!Q;b3' file


          Using a couple of vars makes it a bit better, but not that much



          reg='<item_id>([0-9]*)</item_id>'
          item='6'

          sed -e "h;s,$reg,1,;/^$item$/!d;/^$item$/{g;:1;h;s,$reg,1,;t2;:3;g;n;b1};d;b;:2;/^$item$/!Q;b3" file


          And a POSIXfyed one looks like gibberish:



          sed -ne 'h;s,<item_id>([0-9]*)</item_id>,1,;/^6$/!d;/^6$/{g;:1;h;s,<item_id>([0-9]*)</item_id>,1,;t2;:3;g;p;n;b1;};d;b;:2;/^6$/!q;b3' file


          Only this extended code might(?) be more readable:



          reg='<item_id>([0-9]*)</item_id>'
          item='6'

          sed -ne 'h; # hold copy of line being processed.
          s,'"$reg"',1,; # extract included number.
          /^'"$item"'$/!d; # Not the correct number?: get next line.
          /^'"$item"'$/{
          g; # restore line from hold buffer.
          :1
          h; # store successive lines in hold buffer.
          s,'"$reg"',1,; # extract the number (again).
          t2
          :3
          g; # restore the line back from hold buffer.
          p; # print the line.
          n; # go to process next line.
          b1
          }; # end of loop.
          d; # avoid printing this last line.
          q; # quit the sed script.
          :2
          /^'"$item"'$/!q; # Test if the number is the one selected.
          b3
          ' file


          Maybe you should use some other language or tool.






          share|improve this answer














          Maybe this GNU sed script will work for you:



          sed '/<item_id>6</item_id>/{:1;n;/<item_id>[^6]</item_id>/{Q};b1};d' file


          Keep deleting d lines until a 6 line is found, then keep in the internal loop b1 printing each line until a not 6 ([^6]) line is found, at which time the script is Quit.



          Understand that this works only for one character numbers (the 6 or the 9).





          It gets quite messy to get it to work with any number (GNU):



          sed -e 'h;s,<item_id>([0-9]*)</item_id>,1,;/^6$/!d;/^6$/{g;:1;h;s,<item_id>([0-9]*)</item_id>,1,;t2;:3;g;n;b1};d;b;:2;/^6$/!Q;b3' file


          Using a couple of vars makes it a bit better, but not that much



          reg='<item_id>([0-9]*)</item_id>'
          item='6'

          sed -e "h;s,$reg,1,;/^$item$/!d;/^$item$/{g;:1;h;s,$reg,1,;t2;:3;g;n;b1};d;b;:2;/^$item$/!Q;b3" file


          And a POSIXfyed one looks like gibberish:



          sed -ne 'h;s,<item_id>([0-9]*)</item_id>,1,;/^6$/!d;/^6$/{g;:1;h;s,<item_id>([0-9]*)</item_id>,1,;t2;:3;g;p;n;b1;};d;b;:2;/^6$/!q;b3' file


          Only this extended code might(?) be more readable:



          reg='<item_id>([0-9]*)</item_id>'
          item='6'

          sed -ne 'h; # hold copy of line being processed.
          s,'"$reg"',1,; # extract included number.
          /^'"$item"'$/!d; # Not the correct number?: get next line.
          /^'"$item"'$/{
          g; # restore line from hold buffer.
          :1
          h; # store successive lines in hold buffer.
          s,'"$reg"',1,; # extract the number (again).
          t2
          :3
          g; # restore the line back from hold buffer.
          p; # print the line.
          n; # go to process next line.
          b1
          }; # end of loop.
          d; # avoid printing this last line.
          q; # quit the sed script.
          :2
          /^'"$item"'$/!q; # Test if the number is the one selected.
          b3
          ' file


          Maybe you should use some other language or tool.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 11 at 6:30

























          answered Nov 10 at 20:24









          Isaac

          9,69211445




          9,69211445












          • This will not break out of the loop if the next item has two or three digits, only works with one digit items...
            – Filipe Brandenburger
            Nov 10 at 21:01










          • that's great. almost there. it does not work for a string <item_id>12 until <item_id>15 for example :(.. i tried a few things but cant get it
            – xavi
            Nov 10 at 21:04












          • @FilipeBrandenburger Yes, that is what I said one character numbers. Anyway, a more flexible (but hard to read) solution added.
            – Isaac
            Nov 11 at 6:32










          • thanks! it makes it complicated indeed but this works perfectly. thanks again.
            – xavi
            Nov 11 at 9:52


















          • This will not break out of the loop if the next item has two or three digits, only works with one digit items...
            – Filipe Brandenburger
            Nov 10 at 21:01










          • that's great. almost there. it does not work for a string <item_id>12 until <item_id>15 for example :(.. i tried a few things but cant get it
            – xavi
            Nov 10 at 21:04












          • @FilipeBrandenburger Yes, that is what I said one character numbers. Anyway, a more flexible (but hard to read) solution added.
            – Isaac
            Nov 11 at 6:32










          • thanks! it makes it complicated indeed but this works perfectly. thanks again.
            – xavi
            Nov 11 at 9:52
















          This will not break out of the loop if the next item has two or three digits, only works with one digit items...
          – Filipe Brandenburger
          Nov 10 at 21:01




          This will not break out of the loop if the next item has two or three digits, only works with one digit items...
          – Filipe Brandenburger
          Nov 10 at 21:01












          that's great. almost there. it does not work for a string <item_id>12 until <item_id>15 for example :(.. i tried a few things but cant get it
          – xavi
          Nov 10 at 21:04






          that's great. almost there. it does not work for a string <item_id>12 until <item_id>15 for example :(.. i tried a few things but cant get it
          – xavi
          Nov 10 at 21:04














          @FilipeBrandenburger Yes, that is what I said one character numbers. Anyway, a more flexible (but hard to read) solution added.
          – Isaac
          Nov 11 at 6:32




          @FilipeBrandenburger Yes, that is what I said one character numbers. Anyway, a more flexible (but hard to read) solution added.
          – Isaac
          Nov 11 at 6:32












          thanks! it makes it complicated indeed but this works perfectly. thanks again.
          – xavi
          Nov 11 at 9:52




          thanks! it makes it complicated indeed but this works perfectly. thanks again.
          – xavi
          Nov 11 at 9:52












          up vote
          5
          down vote













          Assuming this is a well-formed XML document, the following uses XMLStarlet to pick out the info_id nodes whose values are 6, and then the immediately following sibling info1 and info2 nodes:



          $ xmlstarlet sel -t -m '//item_id[. = 6]' 
          -c . -nl
          -c './following-sibling::info1[1]' -nl
          -c './following-sibling::info2[1]' -nl file.xml
          <item_id>6</item_id>
          <info1>abc</info1>
          <info2>123</info2>
          <item_id>6</item_id>
          <info1>def</info1>
          <info2>456</info2>
          <item_id>6</item_id>
          <info1>ghi</info1>
          <info2>789</info2>


          Alternatively, to ignore what the following nodes are called:



          xmlstarlet sel -t -m '//item_id[. = 6]' 
          -c . -nl
          -c './following-sibling::*[1]' -nl
          -c './following-sibling::*[2]' -nl file.xml





          share|improve this answer























          • that does the trick! thanks
            – xavi
            Nov 10 at 22:16















          up vote
          5
          down vote













          Assuming this is a well-formed XML document, the following uses XMLStarlet to pick out the info_id nodes whose values are 6, and then the immediately following sibling info1 and info2 nodes:



          $ xmlstarlet sel -t -m '//item_id[. = 6]' 
          -c . -nl
          -c './following-sibling::info1[1]' -nl
          -c './following-sibling::info2[1]' -nl file.xml
          <item_id>6</item_id>
          <info1>abc</info1>
          <info2>123</info2>
          <item_id>6</item_id>
          <info1>def</info1>
          <info2>456</info2>
          <item_id>6</item_id>
          <info1>ghi</info1>
          <info2>789</info2>


          Alternatively, to ignore what the following nodes are called:



          xmlstarlet sel -t -m '//item_id[. = 6]' 
          -c . -nl
          -c './following-sibling::*[1]' -nl
          -c './following-sibling::*[2]' -nl file.xml





          share|improve this answer























          • that does the trick! thanks
            – xavi
            Nov 10 at 22:16













          up vote
          5
          down vote










          up vote
          5
          down vote









          Assuming this is a well-formed XML document, the following uses XMLStarlet to pick out the info_id nodes whose values are 6, and then the immediately following sibling info1 and info2 nodes:



          $ xmlstarlet sel -t -m '//item_id[. = 6]' 
          -c . -nl
          -c './following-sibling::info1[1]' -nl
          -c './following-sibling::info2[1]' -nl file.xml
          <item_id>6</item_id>
          <info1>abc</info1>
          <info2>123</info2>
          <item_id>6</item_id>
          <info1>def</info1>
          <info2>456</info2>
          <item_id>6</item_id>
          <info1>ghi</info1>
          <info2>789</info2>


          Alternatively, to ignore what the following nodes are called:



          xmlstarlet sel -t -m '//item_id[. = 6]' 
          -c . -nl
          -c './following-sibling::*[1]' -nl
          -c './following-sibling::*[2]' -nl file.xml





          share|improve this answer














          Assuming this is a well-formed XML document, the following uses XMLStarlet to pick out the info_id nodes whose values are 6, and then the immediately following sibling info1 and info2 nodes:



          $ xmlstarlet sel -t -m '//item_id[. = 6]' 
          -c . -nl
          -c './following-sibling::info1[1]' -nl
          -c './following-sibling::info2[1]' -nl file.xml
          <item_id>6</item_id>
          <info1>abc</info1>
          <info2>123</info2>
          <item_id>6</item_id>
          <info1>def</info1>
          <info2>456</info2>
          <item_id>6</item_id>
          <info1>ghi</info1>
          <info2>789</info2>


          Alternatively, to ignore what the following nodes are called:



          xmlstarlet sel -t -m '//item_id[. = 6]' 
          -c . -nl
          -c './following-sibling::*[1]' -nl
          -c './following-sibling::*[2]' -nl file.xml






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 10 at 23:13

























          answered Nov 10 at 21:03









          Kusalananda

          116k15218352




          116k15218352












          • that does the trick! thanks
            – xavi
            Nov 10 at 22:16


















          • that does the trick! thanks
            – xavi
            Nov 10 at 22:16
















          that does the trick! thanks
          – xavi
          Nov 10 at 22:16




          that does the trick! thanks
          – xavi
          Nov 10 at 22:16


















           

          draft saved


          draft discarded



















































           


          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f480998%2fsed-extract-lines-until-unmatched-pattern%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

          Full-time equivalent

          さくらももこ

          13 indicted, 8 arrested in Calif. drug cartel investigation