Removing a directory from PATH

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











up vote
16
down vote

favorite
7












I'm trying to compile wxWidgets using MingW, and I have cygwin in my path, which seems to conflict. So I would like to remove /d/Programme/cygwin/bin from the PATH variable and I wonder if there is some elegant way to do this.



The naive approach would be to echo it to a file, remove it manually and source it, but I bet there is better approach to this.










share|improve this question



















  • 2




    Many techniques are listed here: stackoverflow.com/questions/370047/…
    – slm♦
    Jan 11 '14 at 14:41














up vote
16
down vote

favorite
7












I'm trying to compile wxWidgets using MingW, and I have cygwin in my path, which seems to conflict. So I would like to remove /d/Programme/cygwin/bin from the PATH variable and I wonder if there is some elegant way to do this.



The naive approach would be to echo it to a file, remove it manually and source it, but I bet there is better approach to this.










share|improve this question



















  • 2




    Many techniques are listed here: stackoverflow.com/questions/370047/…
    – slm♦
    Jan 11 '14 at 14:41












up vote
16
down vote

favorite
7









up vote
16
down vote

favorite
7






7





I'm trying to compile wxWidgets using MingW, and I have cygwin in my path, which seems to conflict. So I would like to remove /d/Programme/cygwin/bin from the PATH variable and I wonder if there is some elegant way to do this.



The naive approach would be to echo it to a file, remove it manually and source it, but I bet there is better approach to this.










share|improve this question















I'm trying to compile wxWidgets using MingW, and I have cygwin in my path, which seems to conflict. So I would like to remove /d/Programme/cygwin/bin from the PATH variable and I wonder if there is some elegant way to do this.



The naive approach would be to echo it to a file, remove it manually and source it, but I bet there is better approach to this.







bash shell environment-variables path






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 11 '14 at 21:41









Gilles

511k12010141543




511k12010141543










asked Jan 11 '14 at 13:44









Devolus

186116




186116







  • 2




    Many techniques are listed here: stackoverflow.com/questions/370047/…
    – slm♦
    Jan 11 '14 at 14:41












  • 2




    Many techniques are listed here: stackoverflow.com/questions/370047/…
    – slm♦
    Jan 11 '14 at 14:41







2




2




Many techniques are listed here: stackoverflow.com/questions/370047/…
– slm♦
Jan 11 '14 at 14:41




Many techniques are listed here: stackoverflow.com/questions/370047/…
– slm♦
Jan 11 '14 at 14:41










7 Answers
7






active

oldest

votes

















up vote
19
down vote



accepted










There are no standard tools to "edit" the value of $PATH (i.e. "add folder only when it doesn't already exists" or "remove this folder").
You just execute:



export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games


that would be for the current session, if you want to change permanently add it to any .bashrc, bash.bashrc, /etc/profile - whatever fits your system and user needs.
However if you're using BASH, you can also do the following if, let's say, you want to remove the directory /home/wrong/dir/ from your PATH variable, assuming it's at the end:



PATH=$(echo "$PATH" | sed -e 's/:/home/wrong/dir$//')


So in your case you may use



PATH=$(echo "$PATH" | sed -e 's/:/d/Programme/cygwin/bin$//')





share|improve this answer






















  • If the path in question is at the beginning of the PATH variable, you need to match the colon at the end. This is an annoying caveat which complicates easy generic manipulations of PATH variables.
    – Graeme
    Jan 11 '14 at 13:58







  • 3




    When dealing with so many slashes I prefer to change the regex delimiter / with something like |: PATH=$(echo "$PATH" | sed -e 's|:/d/Programme/cygwin/bin$||') to prevent all the escaping.
    – Matthias Kuhn
    Mar 17 '16 at 12:06

















up vote
13
down vote













In bash:



directory_to_remove=/d/Programme/cygwin/bin
PATH=:$PATH:
PATH=$PATH//:$directory_to_remove:/:
PATH=$PATH#:; PATH=$PATH%:


If you don't use an intermediate variable, you need to protect the / characters in the directory to remove so that they aren't reated as the end of the search text.



PATH=:$PATH:
PATH=$PATH//:/d/Programme/cygwin/bin:/:
PATH=$PATH#:; PATH=$PATH%:


The first and third line are there to arrange for every component of the search path to be surrounded by :, to avoid special-casing the first and last component. The second line removes the specified component.






share|improve this answer




















  • Thanks @Gilles, your answer prompted me to come up with my own solution, which only requires three manipulations of PATH rather then four. *8')
    – Mark Booth
    Jun 23 '16 at 11:36

















up vote
7
down vote













After considering other options presented here, and not fully understanding how some of them worked I developed my own path_remove function, which I added to my .bashrc:



function path_remove 
# Delete path by parts so we can never accidentally remove sub paths
PATH=$PATH//":$1:"/":" # delete any instances in the middle
PATH=$PATH/#"$1:"/ # delete any instance at the beginning
PATH=$PATH/%":$1"/ # delete any instance in the at the end



This ended up pretty close to Gilles' solution but wrapped up as a bash function which could be easily used on the command line.



It has the advantages that as a bash function it works like a program without needing to be a program on the path, and it doesn't require any external programs to run, just bash string manipulation.



It appears pretty robust, in particular it doesn't turn somepath:mypath/mysubpath into somepath/mysubpath:if you run path_remove mypath, which was a problem I had with my previous path_remove function.



An excellent explanation of how bash string manipulation works can be found at the Advanced Bash-Scripting Guide.






share|improve this answer





























    up vote
    3
    down vote













    So, combining the answers from @gilles and @bruno-a (and a couple of other sed tricks) I came up with this one-liner, which will remove (every) REMOVE_PART from PATH, regardless of whether it occurs at the beginning, middle or end of PATH



    PATH=$(REMOVE_PART="/d/Programme/cygwin/bin" sh -c 'echo ":$PATH:" | sed "s@:$REMOVE_PART:@:@g;s@^:(.*):$@1@"')


    It's a bit unwieldy, but it's nice to be able to do it in one hit. The ; is used to join together the two separate sed commands:




    • s@:$REMOVE_PART:@:@g (which replaces :$REMOVE_PART: with a single :)


    • s@^:(.*):$@1@ (which strips off the leading and trailing colons we added with the echo command)

    And along similar lines, I've just managed to come up with this one-liner for adding a ADD_PART to the PATH, only if the PATH doesn't already contain it



    PATH=$(ADD_PART="/d/Programme/cygwin/bin" sh -c 'if echo ":$PATH:" | grep -q ":$ADD_PART:"; then echo "$PATH"; else echo "$ADD_PART:$PATH"; fi')


    Change the last part to echo "$PATH:$ADD_PART" if you want to add ADD_PART to the end of PATH instead of to the start.



    ...



    ...or to make this even easier, create a script called remove_path_part with the contents



    echo ":$PATH:" | sed "s@:$1:@:@g;s@^:(.*):$@1@"


    and a script called prepend_path_part with the contents



    if echo ":$PATH:" | grep -q ":$1:"; then echo "$PATH"; else echo "$1:$PATH"; fi


    and a script called append_path_part with the contents



    if echo ":$PATH:" | grep -q ":$1:"; then echo "$PATH"; else echo "$PATH:$1"; fi


    make them all executable, and then call them like:



    • PATH=$(remove_path_part /d/Programme/cygwin/bin)

    • PATH=$(prepend_path_part /d/Programme/cygwin/bin)

    • PATH=$(append_path_part /d/Programme/cygwin/bin)

    Neat, even if I say so myself :-)






    share|improve this answer






















    • I like the suggestion, especially the idea with the scripts.
      – Devolus
      Jan 13 '15 at 9:06

















    up vote
    1
    down vote













    To complete/improve the accepted answer from Tushar, you can:



    • avoid having to escape the slashes in the PATH by using non-slash delimiters

    • omit the -e option, as per the sed man page: "If no -e, --expression, -f, or --file option is given, then the first non-option argument is taken as the sed script to interpret."

    • use the g (global) flag to remove all occurrences

    In the end, it gives something like this:



    PATH=$(echo "$PATH" | sed 's@:/home/wrong/dir$@@g')





    share|improve this answer



























      up vote
      1
      down vote













      It is an interesting exercise to write a bash function to remove a directory from a path variable.



      Here are some functions I use in my .bash* files to append/prepend directories to paths. They have the virtue of removing duplicate entries, if any, and work with any kind of colon separated path variable (PATH, MANPATH, INFOPATH, ...). the remove_from function removes the directory.



      # app,prepend_to path-var-name dirpath
      # remove_from path-var-name dirpath
      #
      # Functions to manipulate a path-style variable. app,prepend_to
      # both remove any other instances of dirname before adding it to
      # the start or end of the path-var-name variable.
      #
      # Calling example:
      # append_to PATH "/usr/local/bin"
      #
      # Uses eval to allow target path varname to be passed in.
      function remove_from() grep --silent ":$2:") &&
      tmp_path=`echo "$tmp_path"
      function append_to()
      remove_from "$1" "$2" # clean the path contents
      eval export $1="$$1:$2"

      function prepend_to()
      remove_from "$1" "$2" # clean the path contents
      eval export $1="$2:$$1"






      share|improve this answer



























        up vote
        0
        down vote













        The current answers don't solve my similar problem in that I need to remove multiple paths. All these paths are sub-directories of a single directory. In that case, this one-liner works for me: (suppose the pattern is cygwin, i.e., removing all paths that contains cygwin)



        pattern=cygwin; export PATH=$(echo $PATH|tr ':' 'n'|sed "#$pattern#d" |tr 'n' ':')





        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%2f108873%2fremoving-a-directory-from-path%23new-answer', 'question_page');

          );

          Post as a guest






























          7 Answers
          7






          active

          oldest

          votes








          7 Answers
          7






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          19
          down vote



          accepted










          There are no standard tools to "edit" the value of $PATH (i.e. "add folder only when it doesn't already exists" or "remove this folder").
          You just execute:



          export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games


          that would be for the current session, if you want to change permanently add it to any .bashrc, bash.bashrc, /etc/profile - whatever fits your system and user needs.
          However if you're using BASH, you can also do the following if, let's say, you want to remove the directory /home/wrong/dir/ from your PATH variable, assuming it's at the end:



          PATH=$(echo "$PATH" | sed -e 's/:/home/wrong/dir$//')


          So in your case you may use



          PATH=$(echo "$PATH" | sed -e 's/:/d/Programme/cygwin/bin$//')





          share|improve this answer






















          • If the path in question is at the beginning of the PATH variable, you need to match the colon at the end. This is an annoying caveat which complicates easy generic manipulations of PATH variables.
            – Graeme
            Jan 11 '14 at 13:58







          • 3




            When dealing with so many slashes I prefer to change the regex delimiter / with something like |: PATH=$(echo "$PATH" | sed -e 's|:/d/Programme/cygwin/bin$||') to prevent all the escaping.
            – Matthias Kuhn
            Mar 17 '16 at 12:06














          up vote
          19
          down vote



          accepted










          There are no standard tools to "edit" the value of $PATH (i.e. "add folder only when it doesn't already exists" or "remove this folder").
          You just execute:



          export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games


          that would be for the current session, if you want to change permanently add it to any .bashrc, bash.bashrc, /etc/profile - whatever fits your system and user needs.
          However if you're using BASH, you can also do the following if, let's say, you want to remove the directory /home/wrong/dir/ from your PATH variable, assuming it's at the end:



          PATH=$(echo "$PATH" | sed -e 's/:/home/wrong/dir$//')


          So in your case you may use



          PATH=$(echo "$PATH" | sed -e 's/:/d/Programme/cygwin/bin$//')





          share|improve this answer






















          • If the path in question is at the beginning of the PATH variable, you need to match the colon at the end. This is an annoying caveat which complicates easy generic manipulations of PATH variables.
            – Graeme
            Jan 11 '14 at 13:58







          • 3




            When dealing with so many slashes I prefer to change the regex delimiter / with something like |: PATH=$(echo "$PATH" | sed -e 's|:/d/Programme/cygwin/bin$||') to prevent all the escaping.
            – Matthias Kuhn
            Mar 17 '16 at 12:06












          up vote
          19
          down vote



          accepted







          up vote
          19
          down vote



          accepted






          There are no standard tools to "edit" the value of $PATH (i.e. "add folder only when it doesn't already exists" or "remove this folder").
          You just execute:



          export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games


          that would be for the current session, if you want to change permanently add it to any .bashrc, bash.bashrc, /etc/profile - whatever fits your system and user needs.
          However if you're using BASH, you can also do the following if, let's say, you want to remove the directory /home/wrong/dir/ from your PATH variable, assuming it's at the end:



          PATH=$(echo "$PATH" | sed -e 's/:/home/wrong/dir$//')


          So in your case you may use



          PATH=$(echo "$PATH" | sed -e 's/:/d/Programme/cygwin/bin$//')





          share|improve this answer














          There are no standard tools to "edit" the value of $PATH (i.e. "add folder only when it doesn't already exists" or "remove this folder").
          You just execute:



          export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games


          that would be for the current session, if you want to change permanently add it to any .bashrc, bash.bashrc, /etc/profile - whatever fits your system and user needs.
          However if you're using BASH, you can also do the following if, let's say, you want to remove the directory /home/wrong/dir/ from your PATH variable, assuming it's at the end:



          PATH=$(echo "$PATH" | sed -e 's/:/home/wrong/dir$//')


          So in your case you may use



          PATH=$(echo "$PATH" | sed -e 's/:/d/Programme/cygwin/bin$//')






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Jan 11 '14 at 23:44









          Gilles

          511k12010141543




          511k12010141543










          answered Jan 11 '14 at 13:53









          tusharmakkar08

          88711020




          88711020











          • If the path in question is at the beginning of the PATH variable, you need to match the colon at the end. This is an annoying caveat which complicates easy generic manipulations of PATH variables.
            – Graeme
            Jan 11 '14 at 13:58







          • 3




            When dealing with so many slashes I prefer to change the regex delimiter / with something like |: PATH=$(echo "$PATH" | sed -e 's|:/d/Programme/cygwin/bin$||') to prevent all the escaping.
            – Matthias Kuhn
            Mar 17 '16 at 12:06
















          • If the path in question is at the beginning of the PATH variable, you need to match the colon at the end. This is an annoying caveat which complicates easy generic manipulations of PATH variables.
            – Graeme
            Jan 11 '14 at 13:58







          • 3




            When dealing with so many slashes I prefer to change the regex delimiter / with something like |: PATH=$(echo "$PATH" | sed -e 's|:/d/Programme/cygwin/bin$||') to prevent all the escaping.
            – Matthias Kuhn
            Mar 17 '16 at 12:06















          If the path in question is at the beginning of the PATH variable, you need to match the colon at the end. This is an annoying caveat which complicates easy generic manipulations of PATH variables.
          – Graeme
          Jan 11 '14 at 13:58





          If the path in question is at the beginning of the PATH variable, you need to match the colon at the end. This is an annoying caveat which complicates easy generic manipulations of PATH variables.
          – Graeme
          Jan 11 '14 at 13:58





          3




          3




          When dealing with so many slashes I prefer to change the regex delimiter / with something like |: PATH=$(echo "$PATH" | sed -e 's|:/d/Programme/cygwin/bin$||') to prevent all the escaping.
          – Matthias Kuhn
          Mar 17 '16 at 12:06




          When dealing with so many slashes I prefer to change the regex delimiter / with something like |: PATH=$(echo "$PATH" | sed -e 's|:/d/Programme/cygwin/bin$||') to prevent all the escaping.
          – Matthias Kuhn
          Mar 17 '16 at 12:06












          up vote
          13
          down vote













          In bash:



          directory_to_remove=/d/Programme/cygwin/bin
          PATH=:$PATH:
          PATH=$PATH//:$directory_to_remove:/:
          PATH=$PATH#:; PATH=$PATH%:


          If you don't use an intermediate variable, you need to protect the / characters in the directory to remove so that they aren't reated as the end of the search text.



          PATH=:$PATH:
          PATH=$PATH//:/d/Programme/cygwin/bin:/:
          PATH=$PATH#:; PATH=$PATH%:


          The first and third line are there to arrange for every component of the search path to be surrounded by :, to avoid special-casing the first and last component. The second line removes the specified component.






          share|improve this answer




















          • Thanks @Gilles, your answer prompted me to come up with my own solution, which only requires three manipulations of PATH rather then four. *8')
            – Mark Booth
            Jun 23 '16 at 11:36














          up vote
          13
          down vote













          In bash:



          directory_to_remove=/d/Programme/cygwin/bin
          PATH=:$PATH:
          PATH=$PATH//:$directory_to_remove:/:
          PATH=$PATH#:; PATH=$PATH%:


          If you don't use an intermediate variable, you need to protect the / characters in the directory to remove so that they aren't reated as the end of the search text.



          PATH=:$PATH:
          PATH=$PATH//:/d/Programme/cygwin/bin:/:
          PATH=$PATH#:; PATH=$PATH%:


          The first and third line are there to arrange for every component of the search path to be surrounded by :, to avoid special-casing the first and last component. The second line removes the specified component.






          share|improve this answer




















          • Thanks @Gilles, your answer prompted me to come up with my own solution, which only requires three manipulations of PATH rather then four. *8')
            – Mark Booth
            Jun 23 '16 at 11:36












          up vote
          13
          down vote










          up vote
          13
          down vote









          In bash:



          directory_to_remove=/d/Programme/cygwin/bin
          PATH=:$PATH:
          PATH=$PATH//:$directory_to_remove:/:
          PATH=$PATH#:; PATH=$PATH%:


          If you don't use an intermediate variable, you need to protect the / characters in the directory to remove so that they aren't reated as the end of the search text.



          PATH=:$PATH:
          PATH=$PATH//:/d/Programme/cygwin/bin:/:
          PATH=$PATH#:; PATH=$PATH%:


          The first and third line are there to arrange for every component of the search path to be surrounded by :, to avoid special-casing the first and last component. The second line removes the specified component.






          share|improve this answer












          In bash:



          directory_to_remove=/d/Programme/cygwin/bin
          PATH=:$PATH:
          PATH=$PATH//:$directory_to_remove:/:
          PATH=$PATH#:; PATH=$PATH%:


          If you don't use an intermediate variable, you need to protect the / characters in the directory to remove so that they aren't reated as the end of the search text.



          PATH=:$PATH:
          PATH=$PATH//:/d/Programme/cygwin/bin:/:
          PATH=$PATH#:; PATH=$PATH%:


          The first and third line are there to arrange for every component of the search path to be surrounded by :, to avoid special-casing the first and last component. The second line removes the specified component.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Jan 11 '14 at 23:42









          Gilles

          511k12010141543




          511k12010141543











          • Thanks @Gilles, your answer prompted me to come up with my own solution, which only requires three manipulations of PATH rather then four. *8')
            – Mark Booth
            Jun 23 '16 at 11:36
















          • Thanks @Gilles, your answer prompted me to come up with my own solution, which only requires three manipulations of PATH rather then four. *8')
            – Mark Booth
            Jun 23 '16 at 11:36















          Thanks @Gilles, your answer prompted me to come up with my own solution, which only requires three manipulations of PATH rather then four. *8')
          – Mark Booth
          Jun 23 '16 at 11:36




          Thanks @Gilles, your answer prompted me to come up with my own solution, which only requires three manipulations of PATH rather then four. *8')
          – Mark Booth
          Jun 23 '16 at 11:36










          up vote
          7
          down vote













          After considering other options presented here, and not fully understanding how some of them worked I developed my own path_remove function, which I added to my .bashrc:



          function path_remove 
          # Delete path by parts so we can never accidentally remove sub paths
          PATH=$PATH//":$1:"/":" # delete any instances in the middle
          PATH=$PATH/#"$1:"/ # delete any instance at the beginning
          PATH=$PATH/%":$1"/ # delete any instance in the at the end



          This ended up pretty close to Gilles' solution but wrapped up as a bash function which could be easily used on the command line.



          It has the advantages that as a bash function it works like a program without needing to be a program on the path, and it doesn't require any external programs to run, just bash string manipulation.



          It appears pretty robust, in particular it doesn't turn somepath:mypath/mysubpath into somepath/mysubpath:if you run path_remove mypath, which was a problem I had with my previous path_remove function.



          An excellent explanation of how bash string manipulation works can be found at the Advanced Bash-Scripting Guide.






          share|improve this answer


























            up vote
            7
            down vote













            After considering other options presented here, and not fully understanding how some of them worked I developed my own path_remove function, which I added to my .bashrc:



            function path_remove 
            # Delete path by parts so we can never accidentally remove sub paths
            PATH=$PATH//":$1:"/":" # delete any instances in the middle
            PATH=$PATH/#"$1:"/ # delete any instance at the beginning
            PATH=$PATH/%":$1"/ # delete any instance in the at the end



            This ended up pretty close to Gilles' solution but wrapped up as a bash function which could be easily used on the command line.



            It has the advantages that as a bash function it works like a program without needing to be a program on the path, and it doesn't require any external programs to run, just bash string manipulation.



            It appears pretty robust, in particular it doesn't turn somepath:mypath/mysubpath into somepath/mysubpath:if you run path_remove mypath, which was a problem I had with my previous path_remove function.



            An excellent explanation of how bash string manipulation works can be found at the Advanced Bash-Scripting Guide.






            share|improve this answer
























              up vote
              7
              down vote










              up vote
              7
              down vote









              After considering other options presented here, and not fully understanding how some of them worked I developed my own path_remove function, which I added to my .bashrc:



              function path_remove 
              # Delete path by parts so we can never accidentally remove sub paths
              PATH=$PATH//":$1:"/":" # delete any instances in the middle
              PATH=$PATH/#"$1:"/ # delete any instance at the beginning
              PATH=$PATH/%":$1"/ # delete any instance in the at the end



              This ended up pretty close to Gilles' solution but wrapped up as a bash function which could be easily used on the command line.



              It has the advantages that as a bash function it works like a program without needing to be a program on the path, and it doesn't require any external programs to run, just bash string manipulation.



              It appears pretty robust, in particular it doesn't turn somepath:mypath/mysubpath into somepath/mysubpath:if you run path_remove mypath, which was a problem I had with my previous path_remove function.



              An excellent explanation of how bash string manipulation works can be found at the Advanced Bash-Scripting Guide.






              share|improve this answer














              After considering other options presented here, and not fully understanding how some of them worked I developed my own path_remove function, which I added to my .bashrc:



              function path_remove 
              # Delete path by parts so we can never accidentally remove sub paths
              PATH=$PATH//":$1:"/":" # delete any instances in the middle
              PATH=$PATH/#"$1:"/ # delete any instance at the beginning
              PATH=$PATH/%":$1"/ # delete any instance in the at the end



              This ended up pretty close to Gilles' solution but wrapped up as a bash function which could be easily used on the command line.



              It has the advantages that as a bash function it works like a program without needing to be a program on the path, and it doesn't require any external programs to run, just bash string manipulation.



              It appears pretty robust, in particular it doesn't turn somepath:mypath/mysubpath into somepath/mysubpath:if you run path_remove mypath, which was a problem I had with my previous path_remove function.



              An excellent explanation of how bash string manipulation works can be found at the Advanced Bash-Scripting Guide.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Apr 13 '17 at 12:37









              Community♦

              1




              1










              answered Jun 23 '16 at 11:34









              Mark Booth

              6581821




              6581821




















                  up vote
                  3
                  down vote













                  So, combining the answers from @gilles and @bruno-a (and a couple of other sed tricks) I came up with this one-liner, which will remove (every) REMOVE_PART from PATH, regardless of whether it occurs at the beginning, middle or end of PATH



                  PATH=$(REMOVE_PART="/d/Programme/cygwin/bin" sh -c 'echo ":$PATH:" | sed "s@:$REMOVE_PART:@:@g;s@^:(.*):$@1@"')


                  It's a bit unwieldy, but it's nice to be able to do it in one hit. The ; is used to join together the two separate sed commands:




                  • s@:$REMOVE_PART:@:@g (which replaces :$REMOVE_PART: with a single :)


                  • s@^:(.*):$@1@ (which strips off the leading and trailing colons we added with the echo command)

                  And along similar lines, I've just managed to come up with this one-liner for adding a ADD_PART to the PATH, only if the PATH doesn't already contain it



                  PATH=$(ADD_PART="/d/Programme/cygwin/bin" sh -c 'if echo ":$PATH:" | grep -q ":$ADD_PART:"; then echo "$PATH"; else echo "$ADD_PART:$PATH"; fi')


                  Change the last part to echo "$PATH:$ADD_PART" if you want to add ADD_PART to the end of PATH instead of to the start.



                  ...



                  ...or to make this even easier, create a script called remove_path_part with the contents



                  echo ":$PATH:" | sed "s@:$1:@:@g;s@^:(.*):$@1@"


                  and a script called prepend_path_part with the contents



                  if echo ":$PATH:" | grep -q ":$1:"; then echo "$PATH"; else echo "$1:$PATH"; fi


                  and a script called append_path_part with the contents



                  if echo ":$PATH:" | grep -q ":$1:"; then echo "$PATH"; else echo "$PATH:$1"; fi


                  make them all executable, and then call them like:



                  • PATH=$(remove_path_part /d/Programme/cygwin/bin)

                  • PATH=$(prepend_path_part /d/Programme/cygwin/bin)

                  • PATH=$(append_path_part /d/Programme/cygwin/bin)

                  Neat, even if I say so myself :-)






                  share|improve this answer






















                  • I like the suggestion, especially the idea with the scripts.
                    – Devolus
                    Jan 13 '15 at 9:06














                  up vote
                  3
                  down vote













                  So, combining the answers from @gilles and @bruno-a (and a couple of other sed tricks) I came up with this one-liner, which will remove (every) REMOVE_PART from PATH, regardless of whether it occurs at the beginning, middle or end of PATH



                  PATH=$(REMOVE_PART="/d/Programme/cygwin/bin" sh -c 'echo ":$PATH:" | sed "s@:$REMOVE_PART:@:@g;s@^:(.*):$@1@"')


                  It's a bit unwieldy, but it's nice to be able to do it in one hit. The ; is used to join together the two separate sed commands:




                  • s@:$REMOVE_PART:@:@g (which replaces :$REMOVE_PART: with a single :)


                  • s@^:(.*):$@1@ (which strips off the leading and trailing colons we added with the echo command)

                  And along similar lines, I've just managed to come up with this one-liner for adding a ADD_PART to the PATH, only if the PATH doesn't already contain it



                  PATH=$(ADD_PART="/d/Programme/cygwin/bin" sh -c 'if echo ":$PATH:" | grep -q ":$ADD_PART:"; then echo "$PATH"; else echo "$ADD_PART:$PATH"; fi')


                  Change the last part to echo "$PATH:$ADD_PART" if you want to add ADD_PART to the end of PATH instead of to the start.



                  ...



                  ...or to make this even easier, create a script called remove_path_part with the contents



                  echo ":$PATH:" | sed "s@:$1:@:@g;s@^:(.*):$@1@"


                  and a script called prepend_path_part with the contents



                  if echo ":$PATH:" | grep -q ":$1:"; then echo "$PATH"; else echo "$1:$PATH"; fi


                  and a script called append_path_part with the contents



                  if echo ":$PATH:" | grep -q ":$1:"; then echo "$PATH"; else echo "$PATH:$1"; fi


                  make them all executable, and then call them like:



                  • PATH=$(remove_path_part /d/Programme/cygwin/bin)

                  • PATH=$(prepend_path_part /d/Programme/cygwin/bin)

                  • PATH=$(append_path_part /d/Programme/cygwin/bin)

                  Neat, even if I say so myself :-)






                  share|improve this answer






















                  • I like the suggestion, especially the idea with the scripts.
                    – Devolus
                    Jan 13 '15 at 9:06












                  up vote
                  3
                  down vote










                  up vote
                  3
                  down vote









                  So, combining the answers from @gilles and @bruno-a (and a couple of other sed tricks) I came up with this one-liner, which will remove (every) REMOVE_PART from PATH, regardless of whether it occurs at the beginning, middle or end of PATH



                  PATH=$(REMOVE_PART="/d/Programme/cygwin/bin" sh -c 'echo ":$PATH:" | sed "s@:$REMOVE_PART:@:@g;s@^:(.*):$@1@"')


                  It's a bit unwieldy, but it's nice to be able to do it in one hit. The ; is used to join together the two separate sed commands:




                  • s@:$REMOVE_PART:@:@g (which replaces :$REMOVE_PART: with a single :)


                  • s@^:(.*):$@1@ (which strips off the leading and trailing colons we added with the echo command)

                  And along similar lines, I've just managed to come up with this one-liner for adding a ADD_PART to the PATH, only if the PATH doesn't already contain it



                  PATH=$(ADD_PART="/d/Programme/cygwin/bin" sh -c 'if echo ":$PATH:" | grep -q ":$ADD_PART:"; then echo "$PATH"; else echo "$ADD_PART:$PATH"; fi')


                  Change the last part to echo "$PATH:$ADD_PART" if you want to add ADD_PART to the end of PATH instead of to the start.



                  ...



                  ...or to make this even easier, create a script called remove_path_part with the contents



                  echo ":$PATH:" | sed "s@:$1:@:@g;s@^:(.*):$@1@"


                  and a script called prepend_path_part with the contents



                  if echo ":$PATH:" | grep -q ":$1:"; then echo "$PATH"; else echo "$1:$PATH"; fi


                  and a script called append_path_part with the contents



                  if echo ":$PATH:" | grep -q ":$1:"; then echo "$PATH"; else echo "$PATH:$1"; fi


                  make them all executable, and then call them like:



                  • PATH=$(remove_path_part /d/Programme/cygwin/bin)

                  • PATH=$(prepend_path_part /d/Programme/cygwin/bin)

                  • PATH=$(append_path_part /d/Programme/cygwin/bin)

                  Neat, even if I say so myself :-)






                  share|improve this answer














                  So, combining the answers from @gilles and @bruno-a (and a couple of other sed tricks) I came up with this one-liner, which will remove (every) REMOVE_PART from PATH, regardless of whether it occurs at the beginning, middle or end of PATH



                  PATH=$(REMOVE_PART="/d/Programme/cygwin/bin" sh -c 'echo ":$PATH:" | sed "s@:$REMOVE_PART:@:@g;s@^:(.*):$@1@"')


                  It's a bit unwieldy, but it's nice to be able to do it in one hit. The ; is used to join together the two separate sed commands:




                  • s@:$REMOVE_PART:@:@g (which replaces :$REMOVE_PART: with a single :)


                  • s@^:(.*):$@1@ (which strips off the leading and trailing colons we added with the echo command)

                  And along similar lines, I've just managed to come up with this one-liner for adding a ADD_PART to the PATH, only if the PATH doesn't already contain it



                  PATH=$(ADD_PART="/d/Programme/cygwin/bin" sh -c 'if echo ":$PATH:" | grep -q ":$ADD_PART:"; then echo "$PATH"; else echo "$ADD_PART:$PATH"; fi')


                  Change the last part to echo "$PATH:$ADD_PART" if you want to add ADD_PART to the end of PATH instead of to the start.



                  ...



                  ...or to make this even easier, create a script called remove_path_part with the contents



                  echo ":$PATH:" | sed "s@:$1:@:@g;s@^:(.*):$@1@"


                  and a script called prepend_path_part with the contents



                  if echo ":$PATH:" | grep -q ":$1:"; then echo "$PATH"; else echo "$1:$PATH"; fi


                  and a script called append_path_part with the contents



                  if echo ":$PATH:" | grep -q ":$1:"; then echo "$PATH"; else echo "$PATH:$1"; fi


                  make them all executable, and then call them like:



                  • PATH=$(remove_path_part /d/Programme/cygwin/bin)

                  • PATH=$(prepend_path_part /d/Programme/cygwin/bin)

                  • PATH=$(append_path_part /d/Programme/cygwin/bin)

                  Neat, even if I say so myself :-)







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Jan 14 '15 at 10:32

























                  answered Jan 13 '15 at 3:56









                  Lurchman

                  413




                  413











                  • I like the suggestion, especially the idea with the scripts.
                    – Devolus
                    Jan 13 '15 at 9:06
















                  • I like the suggestion, especially the idea with the scripts.
                    – Devolus
                    Jan 13 '15 at 9:06















                  I like the suggestion, especially the idea with the scripts.
                  – Devolus
                  Jan 13 '15 at 9:06




                  I like the suggestion, especially the idea with the scripts.
                  – Devolus
                  Jan 13 '15 at 9:06










                  up vote
                  1
                  down vote













                  To complete/improve the accepted answer from Tushar, you can:



                  • avoid having to escape the slashes in the PATH by using non-slash delimiters

                  • omit the -e option, as per the sed man page: "If no -e, --expression, -f, or --file option is given, then the first non-option argument is taken as the sed script to interpret."

                  • use the g (global) flag to remove all occurrences

                  In the end, it gives something like this:



                  PATH=$(echo "$PATH" | sed 's@:/home/wrong/dir$@@g')





                  share|improve this answer
























                    up vote
                    1
                    down vote













                    To complete/improve the accepted answer from Tushar, you can:



                    • avoid having to escape the slashes in the PATH by using non-slash delimiters

                    • omit the -e option, as per the sed man page: "If no -e, --expression, -f, or --file option is given, then the first non-option argument is taken as the sed script to interpret."

                    • use the g (global) flag to remove all occurrences

                    In the end, it gives something like this:



                    PATH=$(echo "$PATH" | sed 's@:/home/wrong/dir$@@g')





                    share|improve this answer






















                      up vote
                      1
                      down vote










                      up vote
                      1
                      down vote









                      To complete/improve the accepted answer from Tushar, you can:



                      • avoid having to escape the slashes in the PATH by using non-slash delimiters

                      • omit the -e option, as per the sed man page: "If no -e, --expression, -f, or --file option is given, then the first non-option argument is taken as the sed script to interpret."

                      • use the g (global) flag to remove all occurrences

                      In the end, it gives something like this:



                      PATH=$(echo "$PATH" | sed 's@:/home/wrong/dir$@@g')





                      share|improve this answer












                      To complete/improve the accepted answer from Tushar, you can:



                      • avoid having to escape the slashes in the PATH by using non-slash delimiters

                      • omit the -e option, as per the sed man page: "If no -e, --expression, -f, or --file option is given, then the first non-option argument is taken as the sed script to interpret."

                      • use the g (global) flag to remove all occurrences

                      In the end, it gives something like this:



                      PATH=$(echo "$PATH" | sed 's@:/home/wrong/dir$@@g')






                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Nov 24 '14 at 10:54









                      Bruno A.

                      111




                      111




















                          up vote
                          1
                          down vote













                          It is an interesting exercise to write a bash function to remove a directory from a path variable.



                          Here are some functions I use in my .bash* files to append/prepend directories to paths. They have the virtue of removing duplicate entries, if any, and work with any kind of colon separated path variable (PATH, MANPATH, INFOPATH, ...). the remove_from function removes the directory.



                          # app,prepend_to path-var-name dirpath
                          # remove_from path-var-name dirpath
                          #
                          # Functions to manipulate a path-style variable. app,prepend_to
                          # both remove any other instances of dirname before adding it to
                          # the start or end of the path-var-name variable.
                          #
                          # Calling example:
                          # append_to PATH "/usr/local/bin"
                          #
                          # Uses eval to allow target path varname to be passed in.
                          function remove_from() grep --silent ":$2:") &&
                          tmp_path=`echo "$tmp_path"
                          function append_to()
                          remove_from "$1" "$2" # clean the path contents
                          eval export $1="$$1:$2"

                          function prepend_to()
                          remove_from "$1" "$2" # clean the path contents
                          eval export $1="$2:$$1"






                          share|improve this answer
























                            up vote
                            1
                            down vote













                            It is an interesting exercise to write a bash function to remove a directory from a path variable.



                            Here are some functions I use in my .bash* files to append/prepend directories to paths. They have the virtue of removing duplicate entries, if any, and work with any kind of colon separated path variable (PATH, MANPATH, INFOPATH, ...). the remove_from function removes the directory.



                            # app,prepend_to path-var-name dirpath
                            # remove_from path-var-name dirpath
                            #
                            # Functions to manipulate a path-style variable. app,prepend_to
                            # both remove any other instances of dirname before adding it to
                            # the start or end of the path-var-name variable.
                            #
                            # Calling example:
                            # append_to PATH "/usr/local/bin"
                            #
                            # Uses eval to allow target path varname to be passed in.
                            function remove_from() grep --silent ":$2:") &&
                            tmp_path=`echo "$tmp_path"
                            function append_to()
                            remove_from "$1" "$2" # clean the path contents
                            eval export $1="$$1:$2"

                            function prepend_to()
                            remove_from "$1" "$2" # clean the path contents
                            eval export $1="$2:$$1"






                            share|improve this answer






















                              up vote
                              1
                              down vote










                              up vote
                              1
                              down vote









                              It is an interesting exercise to write a bash function to remove a directory from a path variable.



                              Here are some functions I use in my .bash* files to append/prepend directories to paths. They have the virtue of removing duplicate entries, if any, and work with any kind of colon separated path variable (PATH, MANPATH, INFOPATH, ...). the remove_from function removes the directory.



                              # app,prepend_to path-var-name dirpath
                              # remove_from path-var-name dirpath
                              #
                              # Functions to manipulate a path-style variable. app,prepend_to
                              # both remove any other instances of dirname before adding it to
                              # the start or end of the path-var-name variable.
                              #
                              # Calling example:
                              # append_to PATH "/usr/local/bin"
                              #
                              # Uses eval to allow target path varname to be passed in.
                              function remove_from() grep --silent ":$2:") &&
                              tmp_path=`echo "$tmp_path"
                              function append_to()
                              remove_from "$1" "$2" # clean the path contents
                              eval export $1="$$1:$2"

                              function prepend_to()
                              remove_from "$1" "$2" # clean the path contents
                              eval export $1="$2:$$1"






                              share|improve this answer












                              It is an interesting exercise to write a bash function to remove a directory from a path variable.



                              Here are some functions I use in my .bash* files to append/prepend directories to paths. They have the virtue of removing duplicate entries, if any, and work with any kind of colon separated path variable (PATH, MANPATH, INFOPATH, ...). the remove_from function removes the directory.



                              # app,prepend_to path-var-name dirpath
                              # remove_from path-var-name dirpath
                              #
                              # Functions to manipulate a path-style variable. app,prepend_to
                              # both remove any other instances of dirname before adding it to
                              # the start or end of the path-var-name variable.
                              #
                              # Calling example:
                              # append_to PATH "/usr/local/bin"
                              #
                              # Uses eval to allow target path varname to be passed in.
                              function remove_from() grep --silent ":$2:") &&
                              tmp_path=`echo "$tmp_path"
                              function append_to()
                              remove_from "$1" "$2" # clean the path contents
                              eval export $1="$$1:$2"

                              function prepend_to()
                              remove_from "$1" "$2" # clean the path contents
                              eval export $1="$2:$$1"







                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered Apr 16 '15 at 20:26









                              Greg Tarsa

                              32916




                              32916




















                                  up vote
                                  0
                                  down vote













                                  The current answers don't solve my similar problem in that I need to remove multiple paths. All these paths are sub-directories of a single directory. In that case, this one-liner works for me: (suppose the pattern is cygwin, i.e., removing all paths that contains cygwin)



                                  pattern=cygwin; export PATH=$(echo $PATH|tr ':' 'n'|sed "#$pattern#d" |tr 'n' ':')





                                  share|improve this answer
























                                    up vote
                                    0
                                    down vote













                                    The current answers don't solve my similar problem in that I need to remove multiple paths. All these paths are sub-directories of a single directory. In that case, this one-liner works for me: (suppose the pattern is cygwin, i.e., removing all paths that contains cygwin)



                                    pattern=cygwin; export PATH=$(echo $PATH|tr ':' 'n'|sed "#$pattern#d" |tr 'n' ':')





                                    share|improve this answer






















                                      up vote
                                      0
                                      down vote










                                      up vote
                                      0
                                      down vote









                                      The current answers don't solve my similar problem in that I need to remove multiple paths. All these paths are sub-directories of a single directory. In that case, this one-liner works for me: (suppose the pattern is cygwin, i.e., removing all paths that contains cygwin)



                                      pattern=cygwin; export PATH=$(echo $PATH|tr ':' 'n'|sed "#$pattern#d" |tr 'n' ':')





                                      share|improve this answer












                                      The current answers don't solve my similar problem in that I need to remove multiple paths. All these paths are sub-directories of a single directory. In that case, this one-liner works for me: (suppose the pattern is cygwin, i.e., removing all paths that contains cygwin)



                                      pattern=cygwin; export PATH=$(echo $PATH|tr ':' 'n'|sed "#$pattern#d" |tr 'n' ':')






                                      share|improve this answer












                                      share|improve this answer



                                      share|improve this answer










                                      answered Sep 7 at 21:07









                                      Penghe Geng

                                      1164




                                      1164



























                                           

                                          draft saved


                                          draft discarded















































                                           


                                          draft saved


                                          draft discarded














                                          StackExchange.ready(
                                          function ()
                                          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f108873%2fremoving-a-directory-from-path%23new-answer', 'question_page');

                                          );

                                          Post as a guest













































































                                          Popular posts from this blog

                                          Peggy Mitchell

                                          Palaiologos

                                          The Forum (Inglewood, California)