How do I manipulate $PATH elements in shell scripts?

前端 未结 12 1143
伪装坚强ぢ
伪装坚强ぢ 2020-11-28 04:03

Is there a idiomatic way of removing elements from PATH-like shell variables?

That is I want to take

PATH=/home/joe/bin:/usr/local/bin:/usr/bin:/bin:         


        
12条回答
  •  庸人自扰
    2020-11-28 04:44

    This is easy using awk.

    Replace

    {
      for(i=1;i<=NF;i++) 
          if($i == REM) 
              if(REP)
                  print REP; 
              else
                  continue;
          else 
              print $i; 
    }
    

    Start it using

    function path_repl {
        echo $PATH | awk -F: -f rem.awk REM="$1" REP="$2" | paste -sd:
    }
    
    $ echo $PATH
    /bin:/usr/bin:/home/js/usr/bin
    $ path_repl /bin /baz
    /baz:/usr/bin:/home/js/usr/bin
    $ path_repl /bin
    /usr/bin:/home/js/usr/bin
    

    Append

    Inserts at the given position. By default, it appends at the end.

    { 
        if(IDX < 1) IDX = NF + IDX + 1
        for(i = 1; i <= NF; i++) {
            if(IDX == i) 
                print REP 
            print $i
        }
        if(IDX == NF + 1)
            print REP
    }
    

    Start it using

    function path_app {
        echo $PATH | awk -F: -f app.awk REP="$1" IDX="$2" | paste -sd:
    }
    
    $ echo $PATH
    /bin:/usr/bin:/home/js/usr/bin
    $ path_app /baz 0
    /bin:/usr/bin:/home/js/usr/bin:/baz
    $ path_app /baz -1
    /bin:/usr/bin:/baz:/home/js/usr/bin
    $ path_app /baz 1
    /baz:/bin:/usr/bin:/home/js/usr/bin
    

    Remove duplicates

    This one keeps the first occurences.

    { 
        for(i = 1; i <= NF; i++) {
            if(!used[$i]) {
                print $i
                used[$i] = 1
            }
        }
    }
    

    Start it like this:

    echo $PATH | awk -F: -f rem_dup.awk | paste -sd:
    

    Validate whether all elements exist

    The following will print an error message for all entries that are not existing in the filesystem, and return a nonzero value.

    echo -n $PATH | xargs -d: stat -c %n
    

    To simply check whether all elements are paths and get a return code, you can also use test:

    echo -n $PATH | xargs -d: -n1 test -d
    

提交回复
热议问题