
PATH環境変数からディレクトリの重複コピーを削除できるbashシェル関数を作成しようとしています。
私はこのコマンドを使って1行のコマンドでこれを行うことができると言われましたが、awk
どうすればいいのかわかりません。これを行う方法を知っている人はいますか?
答え1
まだ重複エントリがなく、PATH
まだ存在しないディレクトリを追加する場合は、シェルのみを使用して簡単にこれを行うことができます。
for x in /path/to/add …; do
case ":$PATH:" in
*":$x:"*) :;; # already there
*) PATH="$x:$PATH";;
esac
done
以下は、重複エントリが削除されるシェルの断片です$PATH
。項目を 1 つずつ見て、まだ表示されていない項目をコピーします。
if [ -n "$PATH" ]; then
old_PATH=$PATH:; PATH=
while [ -n "$old_PATH" ]; do
x=${old_PATH%%:*} # the first remaining entry
case $PATH: in
*:"$x":*) ;; # already there
*) PATH=$PATH:$x;; # not there yet
esac
old_PATH=${old_PATH#*:}
done
PATH=${PATH#:}
unset old_PATH x
fi
答え2
これは理解できる一行のソリューションは、すべての正しい操作を実行します。つまり、重複を排除し、パスの順序を維持し、最後にコロンを追加しません。したがって、元のパスと同じように動作する重複排除されたPATHを提供する必要があります。
PATH="$(perl -e 'print join(":", grep { not $seen{$_}++ } split(/:/, $ENV{PATH}))')"
split(/:/, $ENV{PATH})
コロン()に分割し、useを使用して最初のgrep { not $seen{$_}++ }
出現を除くすべての冗長パスインスタンスをフィルタリングし、コロン(print join(":", ...)
)で区切られた残りのパスを再結合して結果を印刷します。
より多くの構造と他の変数の重複を排除する機能が必要な場合は、次のコードスニペットを試してください。私は現在私の設定で使用しています。
# Deduplicate path variables
get_var () {
eval 'printf "%s\n" "${'"$1"'}"'
}
set_var () {
eval "$1=\"\$2\""
}
dedup_pathvar () {
pathvar_name="$1"
pathvar_value="$(get_var "$pathvar_name")"
deduped_path="$(perl -e 'print join(":",grep { not $seen{$_}++ } split(/:/, $ARGV[0]))' "$pathvar_value")"
set_var "$pathvar_name" "$deduped_path"
}
dedup_pathvar PATH
dedup_pathvar MANPATH
このコードはPATHとMANPATHの重複を排除し、dedup_pathvar
コロンで区切られたパスのリストを保持する他の変数(PYTHONPATHなど)を簡単に呼び出すことができます。
答え3
スタイリッシュなものは次のとおりです。
printf %s "$PATH" | awk -v RS=: -v ORS=: '!arr[$0]++'
より長くなる(操作方法を参照):
printf %s "$PATH" | awk -v RS=: -v ORS=: '{ if (!arr[$0]++) { print $0 } }'
さて、あなたはLinuxを初めて使うので、次の「:」なしでPATHを実際に設定する方法は次のとおりです。
PATH=`printf %s "$PATH" | awk -v RS=: '{ if (!arr[$0]++) {printf("%s%s",!ln++?"":":",$0)}}'`
ちなみに、PATHに「:」を含むディレクトリがないことを確認してください。そうでなければ混乱するでしょう。
いくつかのクレジット:
答え4
awkではなくonelinerを追加する限り:
PATH=$(zsh -fc "typeset -TU P=$PATH p; echo \$P")
(簡単かもしれませんが、zshは常に変更できる少なくともPATH=$(zsh -fc 'typeset -U path; echo $PATH')
1つの設定ファイルを読み込みます。)zshenv
PATH
2つの素晴らしいzsh機能を使用します。
- 配列に関連するスカラー(
typeset -T
) - 重複した値を自動的に削除する配列(
typeset -U
)。