sed or awk to replace string between pattern (convert absolute path to relative)

Multi tool use
Multi tool use

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











up vote
0
down vote

favorite












I am trying to replace all folders in a path with ".."
This is part of a bigger script that will eventually replace some absolute paths into relative paths.



The expected output should look like this:



/ABCDdasda234sEA/asdas2das/asdasf34234/ => /../../../
/ABCDdasda234sEA/asdas2das/asdasf34234/124551assdfa/ => /../../../../


I tried various regex but couldn't get to match correctly, because last "/" is considered ending of the string instead of matching multiple times:



[root@test]# sed "s/^/.*/$//..//g" <<< "/ABCDdasda234sEA/asdasdas/asdasf34234/"

/../









share|improve this question



























    up vote
    0
    down vote

    favorite












    I am trying to replace all folders in a path with ".."
    This is part of a bigger script that will eventually replace some absolute paths into relative paths.



    The expected output should look like this:



    /ABCDdasda234sEA/asdas2das/asdasf34234/ => /../../../
    /ABCDdasda234sEA/asdas2das/asdasf34234/124551assdfa/ => /../../../../


    I tried various regex but couldn't get to match correctly, because last "/" is considered ending of the string instead of matching multiple times:



    [root@test]# sed "s/^/.*/$//..//g" <<< "/ABCDdasda234sEA/asdasdas/asdasf34234/"

    /../









    share|improve this question

























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I am trying to replace all folders in a path with ".."
      This is part of a bigger script that will eventually replace some absolute paths into relative paths.



      The expected output should look like this:



      /ABCDdasda234sEA/asdas2das/asdasf34234/ => /../../../
      /ABCDdasda234sEA/asdas2das/asdasf34234/124551assdfa/ => /../../../../


      I tried various regex but couldn't get to match correctly, because last "/" is considered ending of the string instead of matching multiple times:



      [root@test]# sed "s/^/.*/$//..//g" <<< "/ABCDdasda234sEA/asdasdas/asdasf34234/"

      /../









      share|improve this question















      I am trying to replace all folders in a path with ".."
      This is part of a bigger script that will eventually replace some absolute paths into relative paths.



      The expected output should look like this:



      /ABCDdasda234sEA/asdas2das/asdasf34234/ => /../../../
      /ABCDdasda234sEA/asdas2das/asdasf34234/124551assdfa/ => /../../../../


      I tried various regex but couldn't get to match correctly, because last "/" is considered ending of the string instead of matching multiple times:



      [root@test]# sed "s/^/.*/$//..//g" <<< "/ABCDdasda234sEA/asdasdas/asdasf34234/"

      /../






      awk sed regular-expression






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Sep 26 '17 at 17:19









      Jeff Schaller

      32.3k849110




      32.3k849110










      asked Sep 26 '17 at 14:11









      Futur'Fusionneur

      518




      518




















          4 Answers
          4






          active

          oldest

          votes

















          up vote
          2
          down vote



          accepted










          1) The .* will eat everything including the following slashes, so use [^/]* instead (any number of characters except for the slash)



          2) To avoid the + (for "one or more occurences") which is not available in all sed version simply add a dot requiring at least one character. You don't need another [^/] here if you trust that there is no //



          3) Just for beautification: If the pattern or replacement contain a slash, it's easier to read if you use a different delimiter for the s command like _ or #



          All together:



          sed 's_/.[^/]*_/.._g'





          share|improve this answer




















          • Thank you. giphy.com/gifs/the-office-thank-you-michael-scott-1Z02vuppxP1Pa
            – Futur'Fusionneur
            Sep 26 '17 at 15:27

















          up vote
          2
          down vote













          awk -F/ -v OFS=/ 'for (i=1; i<=NF; i++) if (length($i)) $i = ".."1' <<END
          /ABCDdasda234sEA/asdas2das/asdasf34234/
          /ABCDdasda234sEA/asdas2das/asdasf34234/124551assdfa/
          END




          /../../../
          /../../../../





          share|improve this answer




















          • Thank you this works. I also posted 2 more methods i found meanwhile.
            – Futur'Fusionneur
            Sep 26 '17 at 14:32

















          up vote
          2
          down vote













          I found two more methods meanwhile:



          sed 's:/[[:alnum:]]*:../:g' <<< "/ABCDdasda234sEA/asdasdas/asdasf34234/42346346346/" | sed 's:^..::g'


          awk -F'/' 'for( i = 2; i <= NF-1; i++ ) printf "/../" ' <<< "/ABCDdasda234sEA/asdasdas/asdasf34234/asfasddfg/2345555/" | sed 's//////g'


          Also to include other special characters such as "_":



          sed 's:/[[:alnum:]_]*:../:g' <<< "/ABCDdasda234sEA/asdasdas/asdasf34234/42346346$346/" | sed 's:^..::g'





          share|improve this answer


















          • 1




            Simply include everything but the slash: sed 's_/.[^/]*_/.._g'
            – Philippos
            Sep 26 '17 at 15:07










          • nice, this is elegant. you should post it as an answer instead.
            – Futur'Fusionneur
            Sep 26 '17 at 15:14

















          up vote
          0
          down vote













          Some versions of sed do not accept the advanced features of regular expressions (e.g. + or ) by default. On my system, + works ok.



          Also, you may replace w here with [^/], since file names may contain blanks.






          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%2f394549%2fsed-or-awk-to-replace-string-between-pattern-convert-absolute-path-to-relative%23new-answer', 'question_page');

            );

            Post as a guest






























            4 Answers
            4






            active

            oldest

            votes








            4 Answers
            4






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            2
            down vote



            accepted










            1) The .* will eat everything including the following slashes, so use [^/]* instead (any number of characters except for the slash)



            2) To avoid the + (for "one or more occurences") which is not available in all sed version simply add a dot requiring at least one character. You don't need another [^/] here if you trust that there is no //



            3) Just for beautification: If the pattern or replacement contain a slash, it's easier to read if you use a different delimiter for the s command like _ or #



            All together:



            sed 's_/.[^/]*_/.._g'





            share|improve this answer




















            • Thank you. giphy.com/gifs/the-office-thank-you-michael-scott-1Z02vuppxP1Pa
              – Futur'Fusionneur
              Sep 26 '17 at 15:27














            up vote
            2
            down vote



            accepted










            1) The .* will eat everything including the following slashes, so use [^/]* instead (any number of characters except for the slash)



            2) To avoid the + (for "one or more occurences") which is not available in all sed version simply add a dot requiring at least one character. You don't need another [^/] here if you trust that there is no //



            3) Just for beautification: If the pattern or replacement contain a slash, it's easier to read if you use a different delimiter for the s command like _ or #



            All together:



            sed 's_/.[^/]*_/.._g'





            share|improve this answer




















            • Thank you. giphy.com/gifs/the-office-thank-you-michael-scott-1Z02vuppxP1Pa
              – Futur'Fusionneur
              Sep 26 '17 at 15:27












            up vote
            2
            down vote



            accepted







            up vote
            2
            down vote



            accepted






            1) The .* will eat everything including the following slashes, so use [^/]* instead (any number of characters except for the slash)



            2) To avoid the + (for "one or more occurences") which is not available in all sed version simply add a dot requiring at least one character. You don't need another [^/] here if you trust that there is no //



            3) Just for beautification: If the pattern or replacement contain a slash, it's easier to read if you use a different delimiter for the s command like _ or #



            All together:



            sed 's_/.[^/]*_/.._g'





            share|improve this answer












            1) The .* will eat everything including the following slashes, so use [^/]* instead (any number of characters except for the slash)



            2) To avoid the + (for "one or more occurences") which is not available in all sed version simply add a dot requiring at least one character. You don't need another [^/] here if you trust that there is no //



            3) Just for beautification: If the pattern or replacement contain a slash, it's easier to read if you use a different delimiter for the s command like _ or #



            All together:



            sed 's_/.[^/]*_/.._g'






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Sep 26 '17 at 15:21









            Philippos

            5,95211546




            5,95211546











            • Thank you. giphy.com/gifs/the-office-thank-you-michael-scott-1Z02vuppxP1Pa
              – Futur'Fusionneur
              Sep 26 '17 at 15:27
















            • Thank you. giphy.com/gifs/the-office-thank-you-michael-scott-1Z02vuppxP1Pa
              – Futur'Fusionneur
              Sep 26 '17 at 15:27















            Thank you. giphy.com/gifs/the-office-thank-you-michael-scott-1Z02vuppxP1Pa
            – Futur'Fusionneur
            Sep 26 '17 at 15:27




            Thank you. giphy.com/gifs/the-office-thank-you-michael-scott-1Z02vuppxP1Pa
            – Futur'Fusionneur
            Sep 26 '17 at 15:27












            up vote
            2
            down vote













            awk -F/ -v OFS=/ 'for (i=1; i<=NF; i++) if (length($i)) $i = ".."1' <<END
            /ABCDdasda234sEA/asdas2das/asdasf34234/
            /ABCDdasda234sEA/asdas2das/asdasf34234/124551assdfa/
            END




            /../../../
            /../../../../





            share|improve this answer




















            • Thank you this works. I also posted 2 more methods i found meanwhile.
              – Futur'Fusionneur
              Sep 26 '17 at 14:32














            up vote
            2
            down vote













            awk -F/ -v OFS=/ 'for (i=1; i<=NF; i++) if (length($i)) $i = ".."1' <<END
            /ABCDdasda234sEA/asdas2das/asdasf34234/
            /ABCDdasda234sEA/asdas2das/asdasf34234/124551assdfa/
            END




            /../../../
            /../../../../





            share|improve this answer




















            • Thank you this works. I also posted 2 more methods i found meanwhile.
              – Futur'Fusionneur
              Sep 26 '17 at 14:32












            up vote
            2
            down vote










            up vote
            2
            down vote









            awk -F/ -v OFS=/ 'for (i=1; i<=NF; i++) if (length($i)) $i = ".."1' <<END
            /ABCDdasda234sEA/asdas2das/asdasf34234/
            /ABCDdasda234sEA/asdas2das/asdasf34234/124551assdfa/
            END




            /../../../
            /../../../../





            share|improve this answer












            awk -F/ -v OFS=/ 'for (i=1; i<=NF; i++) if (length($i)) $i = ".."1' <<END
            /ABCDdasda234sEA/asdas2das/asdasf34234/
            /ABCDdasda234sEA/asdas2das/asdasf34234/124551assdfa/
            END




            /../../../
            /../../../../






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Sep 26 '17 at 14:18









            glenn jackman

            47.4k265103




            47.4k265103











            • Thank you this works. I also posted 2 more methods i found meanwhile.
              – Futur'Fusionneur
              Sep 26 '17 at 14:32
















            • Thank you this works. I also posted 2 more methods i found meanwhile.
              – Futur'Fusionneur
              Sep 26 '17 at 14:32















            Thank you this works. I also posted 2 more methods i found meanwhile.
            – Futur'Fusionneur
            Sep 26 '17 at 14:32




            Thank you this works. I also posted 2 more methods i found meanwhile.
            – Futur'Fusionneur
            Sep 26 '17 at 14:32










            up vote
            2
            down vote













            I found two more methods meanwhile:



            sed 's:/[[:alnum:]]*:../:g' <<< "/ABCDdasda234sEA/asdasdas/asdasf34234/42346346346/" | sed 's:^..::g'


            awk -F'/' 'for( i = 2; i <= NF-1; i++ ) printf "/../" ' <<< "/ABCDdasda234sEA/asdasdas/asdasf34234/asfasddfg/2345555/" | sed 's//////g'


            Also to include other special characters such as "_":



            sed 's:/[[:alnum:]_]*:../:g' <<< "/ABCDdasda234sEA/asdasdas/asdasf34234/42346346$346/" | sed 's:^..::g'





            share|improve this answer


















            • 1




              Simply include everything but the slash: sed 's_/.[^/]*_/.._g'
              – Philippos
              Sep 26 '17 at 15:07










            • nice, this is elegant. you should post it as an answer instead.
              – Futur'Fusionneur
              Sep 26 '17 at 15:14














            up vote
            2
            down vote













            I found two more methods meanwhile:



            sed 's:/[[:alnum:]]*:../:g' <<< "/ABCDdasda234sEA/asdasdas/asdasf34234/42346346346/" | sed 's:^..::g'


            awk -F'/' 'for( i = 2; i <= NF-1; i++ ) printf "/../" ' <<< "/ABCDdasda234sEA/asdasdas/asdasf34234/asfasddfg/2345555/" | sed 's//////g'


            Also to include other special characters such as "_":



            sed 's:/[[:alnum:]_]*:../:g' <<< "/ABCDdasda234sEA/asdasdas/asdasf34234/42346346$346/" | sed 's:^..::g'





            share|improve this answer


















            • 1




              Simply include everything but the slash: sed 's_/.[^/]*_/.._g'
              – Philippos
              Sep 26 '17 at 15:07










            • nice, this is elegant. you should post it as an answer instead.
              – Futur'Fusionneur
              Sep 26 '17 at 15:14












            up vote
            2
            down vote










            up vote
            2
            down vote









            I found two more methods meanwhile:



            sed 's:/[[:alnum:]]*:../:g' <<< "/ABCDdasda234sEA/asdasdas/asdasf34234/42346346346/" | sed 's:^..::g'


            awk -F'/' 'for( i = 2; i <= NF-1; i++ ) printf "/../" ' <<< "/ABCDdasda234sEA/asdasdas/asdasf34234/asfasddfg/2345555/" | sed 's//////g'


            Also to include other special characters such as "_":



            sed 's:/[[:alnum:]_]*:../:g' <<< "/ABCDdasda234sEA/asdasdas/asdasf34234/42346346$346/" | sed 's:^..::g'





            share|improve this answer














            I found two more methods meanwhile:



            sed 's:/[[:alnum:]]*:../:g' <<< "/ABCDdasda234sEA/asdasdas/asdasf34234/42346346346/" | sed 's:^..::g'


            awk -F'/' 'for( i = 2; i <= NF-1; i++ ) printf "/../" ' <<< "/ABCDdasda234sEA/asdasdas/asdasf34234/asfasddfg/2345555/" | sed 's//////g'


            Also to include other special characters such as "_":



            sed 's:/[[:alnum:]_]*:../:g' <<< "/ABCDdasda234sEA/asdasdas/asdasf34234/42346346$346/" | sed 's:^..::g'






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Sep 26 '17 at 14:44

























            answered Sep 26 '17 at 14:31









            Futur'Fusionneur

            518




            518







            • 1




              Simply include everything but the slash: sed 's_/.[^/]*_/.._g'
              – Philippos
              Sep 26 '17 at 15:07










            • nice, this is elegant. you should post it as an answer instead.
              – Futur'Fusionneur
              Sep 26 '17 at 15:14












            • 1




              Simply include everything but the slash: sed 's_/.[^/]*_/.._g'
              – Philippos
              Sep 26 '17 at 15:07










            • nice, this is elegant. you should post it as an answer instead.
              – Futur'Fusionneur
              Sep 26 '17 at 15:14







            1




            1




            Simply include everything but the slash: sed 's_/.[^/]*_/.._g'
            – Philippos
            Sep 26 '17 at 15:07




            Simply include everything but the slash: sed 's_/.[^/]*_/.._g'
            – Philippos
            Sep 26 '17 at 15:07












            nice, this is elegant. you should post it as an answer instead.
            – Futur'Fusionneur
            Sep 26 '17 at 15:14




            nice, this is elegant. you should post it as an answer instead.
            – Futur'Fusionneur
            Sep 26 '17 at 15:14










            up vote
            0
            down vote













            Some versions of sed do not accept the advanced features of regular expressions (e.g. + or ) by default. On my system, + works ok.



            Also, you may replace w here with [^/], since file names may contain blanks.






            share|improve this answer
























              up vote
              0
              down vote













              Some versions of sed do not accept the advanced features of regular expressions (e.g. + or ) by default. On my system, + works ok.



              Also, you may replace w here with [^/], since file names may contain blanks.






              share|improve this answer






















                up vote
                0
                down vote










                up vote
                0
                down vote









                Some versions of sed do not accept the advanced features of regular expressions (e.g. + or ) by default. On my system, + works ok.



                Also, you may replace w here with [^/], since file names may contain blanks.






                share|improve this answer












                Some versions of sed do not accept the advanced features of regular expressions (e.g. + or ) by default. On my system, + works ok.



                Also, you may replace w here with [^/], since file names may contain blanks.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Sep 26 '17 at 14:39









                Amos Shapir

                11




                11



























                     

                    draft saved


                    draft discarded















































                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f394549%2fsed-or-awk-to-replace-string-between-pattern-convert-absolute-path-to-relative%23new-answer', 'question_page');

                    );

                    Post as a guest













































































                    uV ARZc00zWj0hqE57tHmOJlq5T Hm1zHPxh4nHa7OJOJqTNr,zFAn9MPBz zoF1AJvc8jn Ik0OTZWJ7WtiZGZldbJlfL,3k3InZ
                    Th5w,FVkpO UEQI6wGJNE76SlAU2V,waaZYaVYxoSTnK ke3E0tg0nJpcriVlGWY6R,O1fBNjb2I

                    Popular posts from this blog

                    How to check contact read email or not when send email to Individual?

                    How many registers does an x86_64 CPU actually have?

                    Displaying single band from multi-band raster using QGIS