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

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













































































                    Popular posts from this blog

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

                    Displaying single band from multi-band raster using QGIS

                    How many registers does an x86_64 CPU actually have?