Category: Utility Code
Author/Contact Info aepage@users.sourceforge.net
Description: Perl -e command for scrubbing duplicate directories out of your PATH variable in bash, sh and ksh. Place after the last modification of the PATH. Order of the entries is preserved.

export PATH=`perl -e 'print join ":", (grep $h{$_}++ < 1, split /:/,$E
+NV{PATH}), "\n" ;'`

Nuts and Bolts

Unix path specifications are delimited by colons(:). The line breaks the existing entry into a list of separate directories1. It then iterates over that list, at each directory it references an entry in the %h hash and increments it2. If the entry previously did not exist, the entry will be undef, the entry will be added to a new list. If the entry already exists, it will be skipped. The resulting list is then passed to 'join' where the entries will be joined into a string, with a ":" between each entry3. The result is printed4. This expression is evaluated by the -e option of perl5 and put back into the PATH variable with the ``6.

  • 1 split/:/, $ENV{PATH} produces a list of separate entries. PATH=/usr/bin:/usr/ccs/bin:/bin, becomes (/usr/bin, /usr/ccs/bin, /bin)
  • 2 grep $h{$_}++ < 1 grep iterates over a list, in this case, the list produced by the split in 1. At each step it sets $_ to the current entry and evaluates the expression "$h{$_}++ < 1". $h{$_}++ does a lookup in the %h hash and increments it and compares tests the pre-increment value to see if it's less than one. When the hash does not already contain an entry for $_ (the current directory being examined) this test will be TRUE, and simulaneously puts a 1 into that slot in the hash. If the expression sees another entry for the same directory that test will now be FALSE, and so the entry will not be included in grep's result.
  • 3 join ":" takes the result of the grep and catenates the entries together, separating them with ":".
  • 4 print outputs the whole result, a new string that will be suitable for a PATH variable.
  • 5 perl -e '...' The -e str command line option tells perl to take the string between the '' and evaluate it.
  • 6 export PATH=`cmd` (or setenv PATH `cmd` for csh) executes the command between the backticks(` very different from the ' or ") and sets PATH to the value of the result.
  • Replies are listed 'Best First'.
    Re: PATH environmental variable scrubber
    by Yendor (Pilgrim) on Oct 09, 2003 at 21:15 UTC
      And for those of us who use shells with a "c" in their name: setenv PATH `perl -e 'print join ":", (grep $h{$_}++ < 1, split /:/,$ENV{PATH}), "\n" ;'`

      -Yendor

      IWeThey
      HOPE Ride

    •Re: PATH environmental variable scrubber
    by merlyn (Sage) on Oct 09, 2003 at 22:16 UTC
        It's "environment variables", not "environmental variables".
        And then there's environmental environment variables, like:
        $ENV{clean_water} = "good"; $ENV{clean_air} = "good"; $ENV{oil_spill} = "bad";
        I'll go back and hide under my rock now...

        <comment mode="nitpick>

        <comment mode="severe pedant">
        You forgot the closing " on your mode attribute...
        </comment>

        ;-)

        -Yendor

        IWeThey
        HOPE Ride