How to find a text, copy it and insert in next line in a file?











up vote
2
down vote

favorite












I'm trying to write a script that processes .xml file. It has to find all lines with a <title> element, copy it, and paste in a next line after that found one, but also changing the element type. Here is an example.



Original:




some text
<title>text 1</title>

some text
<title>text 2</title>

some text




And this is what I need to get:




some text
<title>text 1</title>
<description>text 1</description>

some text
<title>text 2</title>
<description>text 2</description>

some text




Can it be done with sed or grep (or some other tool)?










share|improve this question
























  • why the second <title> line has text 1 in the result? a typo?
    – RomanPerekhrest
    Jul 11 '17 at 22:02












  • yes, it was a typo, i've corrected it
    – xjr
    Jul 20 '17 at 21:41















up vote
2
down vote

favorite












I'm trying to write a script that processes .xml file. It has to find all lines with a <title> element, copy it, and paste in a next line after that found one, but also changing the element type. Here is an example.



Original:




some text
<title>text 1</title>

some text
<title>text 2</title>

some text




And this is what I need to get:




some text
<title>text 1</title>
<description>text 1</description>

some text
<title>text 2</title>
<description>text 2</description>

some text




Can it be done with sed or grep (or some other tool)?










share|improve this question
























  • why the second <title> line has text 1 in the result? a typo?
    – RomanPerekhrest
    Jul 11 '17 at 22:02












  • yes, it was a typo, i've corrected it
    – xjr
    Jul 20 '17 at 21:41













up vote
2
down vote

favorite









up vote
2
down vote

favorite











I'm trying to write a script that processes .xml file. It has to find all lines with a <title> element, copy it, and paste in a next line after that found one, but also changing the element type. Here is an example.



Original:




some text
<title>text 1</title>

some text
<title>text 2</title>

some text




And this is what I need to get:




some text
<title>text 1</title>
<description>text 1</description>

some text
<title>text 2</title>
<description>text 2</description>

some text




Can it be done with sed or grep (or some other tool)?










share|improve this question















I'm trying to write a script that processes .xml file. It has to find all lines with a <title> element, copy it, and paste in a next line after that found one, but also changing the element type. Here is an example.



Original:




some text
<title>text 1</title>

some text
<title>text 2</title>

some text




And this is what I need to get:




some text
<title>text 1</title>
<description>text 1</description>

some text
<title>text 2</title>
<description>text 2</description>

some text




Can it be done with sed or grep (or some other tool)?







text-processing sed grep scripting xml






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jul 20 '17 at 21:41

























asked Jul 11 '17 at 21:57









xjr

134




134












  • why the second <title> line has text 1 in the result? a typo?
    – RomanPerekhrest
    Jul 11 '17 at 22:02












  • yes, it was a typo, i've corrected it
    – xjr
    Jul 20 '17 at 21:41


















  • why the second <title> line has text 1 in the result? a typo?
    – RomanPerekhrest
    Jul 11 '17 at 22:02












  • yes, it was a typo, i've corrected it
    – xjr
    Jul 20 '17 at 21:41
















why the second <title> line has text 1 in the result? a typo?
– RomanPerekhrest
Jul 11 '17 at 22:02






why the second <title> line has text 1 in the result? a typo?
– RomanPerekhrest
Jul 11 '17 at 22:02














yes, it was a typo, i've corrected it
– xjr
Jul 20 '17 at 21:41




yes, it was a typo, i've corrected it
– xjr
Jul 20 '17 at 21:41










2 Answers
2






active

oldest

votes

















up vote
1
down vote



accepted










sed -E 's%<title>(.*)</title>%<title>1</title>n<desc>1</desc>%g' file.xml should do your homework.



To explain it a bit further:
-E parameter tells sed to use extended regular expressions, so you can use references. Replacing with sed is normally done in the form s/search/replace/g. As there are slashes in the search text we use % instead of / for sed to mark the parts, so we do not have to mask the slashes in the search text by a backslash. The rest is normal regex stuff, 1 in the replace part references the snippet inside (…) in the search part.






share|improve this answer























  • This answer needs explanation.
    – countermode
    Jul 12 '17 at 22:09










  • Thank you, it works. I have not analyzed it yet, but it works!
    – xjr
    Jul 20 '17 at 21:55


















up vote
3
down vote













XML parsers/processors are the right tools for manipulating XML data.



xmlstarlet solution:



the exemplary input.xml content:



<root>
some text
<title>text 1</title>
some text
<title>text 2</title>
some text </root>




xmlstarlet ed -a '//title' -t elem -n 'description' -v '' input.xml 
| xmlstarlet ed -u '//description' -x './preceding-sibling::title[1]/text()'


The output:



<?xml version="1.0"?>
<root>
some text
<title>text 1</title><description>text 1</description>
some text
<title>text 2</title><description>text 2</description>
some text </root>





  • ed - edit mode


  • -a - append action


  • -u - update action







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: 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%2f377819%2fhow-to-find-a-text-copy-it-and-insert-in-next-line-in-a-file%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
    1
    down vote



    accepted










    sed -E 's%<title>(.*)</title>%<title>1</title>n<desc>1</desc>%g' file.xml should do your homework.



    To explain it a bit further:
    -E parameter tells sed to use extended regular expressions, so you can use references. Replacing with sed is normally done in the form s/search/replace/g. As there are slashes in the search text we use % instead of / for sed to mark the parts, so we do not have to mask the slashes in the search text by a backslash. The rest is normal regex stuff, 1 in the replace part references the snippet inside (…) in the search part.






    share|improve this answer























    • This answer needs explanation.
      – countermode
      Jul 12 '17 at 22:09










    • Thank you, it works. I have not analyzed it yet, but it works!
      – xjr
      Jul 20 '17 at 21:55















    up vote
    1
    down vote



    accepted










    sed -E 's%<title>(.*)</title>%<title>1</title>n<desc>1</desc>%g' file.xml should do your homework.



    To explain it a bit further:
    -E parameter tells sed to use extended regular expressions, so you can use references. Replacing with sed is normally done in the form s/search/replace/g. As there are slashes in the search text we use % instead of / for sed to mark the parts, so we do not have to mask the slashes in the search text by a backslash. The rest is normal regex stuff, 1 in the replace part references the snippet inside (…) in the search part.






    share|improve this answer























    • This answer needs explanation.
      – countermode
      Jul 12 '17 at 22:09










    • Thank you, it works. I have not analyzed it yet, but it works!
      – xjr
      Jul 20 '17 at 21:55













    up vote
    1
    down vote



    accepted







    up vote
    1
    down vote



    accepted






    sed -E 's%<title>(.*)</title>%<title>1</title>n<desc>1</desc>%g' file.xml should do your homework.



    To explain it a bit further:
    -E parameter tells sed to use extended regular expressions, so you can use references. Replacing with sed is normally done in the form s/search/replace/g. As there are slashes in the search text we use % instead of / for sed to mark the parts, so we do not have to mask the slashes in the search text by a backslash. The rest is normal regex stuff, 1 in the replace part references the snippet inside (…) in the search part.






    share|improve this answer














    sed -E 's%<title>(.*)</title>%<title>1</title>n<desc>1</desc>%g' file.xml should do your homework.



    To explain it a bit further:
    -E parameter tells sed to use extended regular expressions, so you can use references. Replacing with sed is normally done in the form s/search/replace/g. As there are slashes in the search text we use % instead of / for sed to mark the parts, so we do not have to mask the slashes in the search text by a backslash. The rest is normal regex stuff, 1 in the replace part references the snippet inside (…) in the search part.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Dec 3 at 20:20

























    answered Jul 12 '17 at 21:41









    Jaleks

    1,203422




    1,203422












    • This answer needs explanation.
      – countermode
      Jul 12 '17 at 22:09










    • Thank you, it works. I have not analyzed it yet, but it works!
      – xjr
      Jul 20 '17 at 21:55


















    • This answer needs explanation.
      – countermode
      Jul 12 '17 at 22:09










    • Thank you, it works. I have not analyzed it yet, but it works!
      – xjr
      Jul 20 '17 at 21:55
















    This answer needs explanation.
    – countermode
    Jul 12 '17 at 22:09




    This answer needs explanation.
    – countermode
    Jul 12 '17 at 22:09












    Thank you, it works. I have not analyzed it yet, but it works!
    – xjr
    Jul 20 '17 at 21:55




    Thank you, it works. I have not analyzed it yet, but it works!
    – xjr
    Jul 20 '17 at 21:55












    up vote
    3
    down vote













    XML parsers/processors are the right tools for manipulating XML data.



    xmlstarlet solution:



    the exemplary input.xml content:



    <root>
    some text
    <title>text 1</title>
    some text
    <title>text 2</title>
    some text </root>




    xmlstarlet ed -a '//title' -t elem -n 'description' -v '' input.xml 
    | xmlstarlet ed -u '//description' -x './preceding-sibling::title[1]/text()'


    The output:



    <?xml version="1.0"?>
    <root>
    some text
    <title>text 1</title><description>text 1</description>
    some text
    <title>text 2</title><description>text 2</description>
    some text </root>





    • ed - edit mode


    • -a - append action


    • -u - update action







    share|improve this answer

























      up vote
      3
      down vote













      XML parsers/processors are the right tools for manipulating XML data.



      xmlstarlet solution:



      the exemplary input.xml content:



      <root>
      some text
      <title>text 1</title>
      some text
      <title>text 2</title>
      some text </root>




      xmlstarlet ed -a '//title' -t elem -n 'description' -v '' input.xml 
      | xmlstarlet ed -u '//description' -x './preceding-sibling::title[1]/text()'


      The output:



      <?xml version="1.0"?>
      <root>
      some text
      <title>text 1</title><description>text 1</description>
      some text
      <title>text 2</title><description>text 2</description>
      some text </root>





      • ed - edit mode


      • -a - append action


      • -u - update action







      share|improve this answer























        up vote
        3
        down vote










        up vote
        3
        down vote









        XML parsers/processors are the right tools for manipulating XML data.



        xmlstarlet solution:



        the exemplary input.xml content:



        <root>
        some text
        <title>text 1</title>
        some text
        <title>text 2</title>
        some text </root>




        xmlstarlet ed -a '//title' -t elem -n 'description' -v '' input.xml 
        | xmlstarlet ed -u '//description' -x './preceding-sibling::title[1]/text()'


        The output:



        <?xml version="1.0"?>
        <root>
        some text
        <title>text 1</title><description>text 1</description>
        some text
        <title>text 2</title><description>text 2</description>
        some text </root>





        • ed - edit mode


        • -a - append action


        • -u - update action







        share|improve this answer












        XML parsers/processors are the right tools for manipulating XML data.



        xmlstarlet solution:



        the exemplary input.xml content:



        <root>
        some text
        <title>text 1</title>
        some text
        <title>text 2</title>
        some text </root>




        xmlstarlet ed -a '//title' -t elem -n 'description' -v '' input.xml 
        | xmlstarlet ed -u '//description' -x './preceding-sibling::title[1]/text()'


        The output:



        <?xml version="1.0"?>
        <root>
        some text
        <title>text 1</title><description>text 1</description>
        some text
        <title>text 2</title><description>text 2</description>
        some text </root>





        • ed - edit mode


        • -a - append action


        • -u - update action








        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jul 11 '17 at 22:20









        RomanPerekhrest

        22.8k12246




        22.8k12246






























            draft saved

            draft discarded




















































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


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

            But avoid



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

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


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





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


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

            But avoid



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

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


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




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f377819%2fhow-to-find-a-text-copy-it-and-insert-in-next-line-in-a-file%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

            Morgemoulin

            Scott Moir

            Souastre