anaconda
またはminiconda
という名前のディレクトリがユーザー_$HOME
_にあるかどうかを確認する小さなbashスクリプトを作成しました。しかし、私の家では_miniconda2
_ディレクトリが見つかりません。
どうすれば修正できますか?
_if [ -d "$HOME"/"(ana|mini)conda[0-9]?" ]; then
echo "miniconda directory is found in your $HOME"
else
echo "anaconda/miniconda is not found in your $HOME"
fi
_
PS:_[ -d "$HOME"/miniconda2 ]; then
_がある場合、miniconda2ディレクトリが見つかったため、エラーは"(ana|mini)conda[0-9]?"
の部分にあると思います
スクリプトは一般的なものにしてください。私にとっては、miniconda2ですが、他のユーザーにとっては、anaconda2、miniconda3などです。
これは、うまく行うには驚くほどトリッキーなことです。
基本的に、_-d
_は、正規表現を使用してファイル名を照合できる場合でも、単一の引数のみをテストします。
1つの方法は、問題を反転させ、ディレクトリの正規表現の一致をテストする代わりに、正規表現の一致のディレクトリをテストすることです。言い換えると、単純なシェルグロブを使用して_$HOME
_のディレクトリをallでループオーバーし、正規表現に対してそれぞれをテストして、一致を破ります、最後に_BASH_REMATCH
_配列が空でないかどうかをテストします。
_#!/bin/bash
for d in "$HOME"/*/; do
if [[ $d =~ (ana|mini)conda[0-9]? ]]; then
break;
fi
done
if ((${#BASH_REMATCH[@]} > 0)); then
echo "anaconda/miniconda directory is found in your $HOME"
else
echo "anaconda/miniconda is not found in your $HOME"
fi
_
別の方法は、正規表現の代わりに拡張シェルグロブを使用し、配列内のグロブの一致をキャプチャすることです。次に、配列が空でないかどうかをテストします。
_#!/bin/bash
shopt -s extglob nullglob
dirs=( "$HOME"/@(ana|mini)conda?([0-9])/ )
if (( ${#dirs[@]} > 0 )); then
echo "anaconda/miniconda directory is found in your $HOME"
else
echo "anaconda/miniconda is not found in your $HOME"
fi
_
末尾の_/
_は、ディレクトリのみが一致することを保証します。 nullglob
は、一致がゼロの場合にシェルが一致しない文字列を返すのを防ぎます。
どちらかを再帰的にするには、globstar
シェルオプション(_shopt -s globstar
_)を設定してから、それぞれ:-
(正規表現バージョン):_for d in "$HOME"/**/; do
_
(拡張グロブバージョン):dirs=( "$HOME"/**/@(ana|mini)conda?([0-9])/ )
実際、すでに述べたように、これはトリッキーです。私のアプローチは次のとおりです:
find
とそのregex機能を使用して、問題のディレクトリを見つけます。find
にx
を出力させるx
esを文字列に格納するしたがって:
_xString=$(find $HOME -maxdepth 1 \
-type d \
-regextype egrep \
-regex "$HOME/(ana|mini)conda[0-9]?" \
-printf 'x');
if [ -n "$xString" ]; then
echo "found one of the directories";
else
echo "no match.";
fi
_
説明:
find $HOME -maxdepth 1
_は、_$HOME
_以下のすべてを検索しますが、検索を1レベルに制限します(つまり、サブディレクトリに再帰しません)。-type d
_は、検索をd
irectoriesのみに制限します-regextype egrep
_は、find
にどのタイプの正規表現を処理するかを指示します。これは、_[0-9]?
_や_(…|…)
_のようなものが特別であり、find
がデフォルトでそれらを認識しないために必要です。-regex "$HOME/(ana|mini)conda[0-9]?"
は、実際に必要な正規表現です。-printf 'x'
_は、前の条件を満たすすべてのthingに対してx
を出力するだけです。テストしたいディレクトリ名のリストをループして、それらのいずれかが存在する場合はそれに対処することができます。
a=0
for i in {ana,mini}conda{,2}; do
if [ -d "$i" ]; then
unset a
break
fi
done
echo "anaconda/miniconda directory is ${a+not }found in your $HOME"
このソリューションでは、完全な正規表現の力は明らかに許可されませんが、シェルのグロビングとブレースの拡張は、少なくともあなたが示したケースでは同等です。ループは、1つのディレクトリが存在するとすぐに終了し、以前に設定された変数a
の設定を解除します。次のecho
行では、 パラメータ展開${a+not }
は、a
が設定されている(= dirが見つからない)場合は何も展開せず、それ以外の場合は「not」に展開されます。
考えられる回避策は、次に示すように、ミニコンダとアナコンダを別々に検索することです。
if [ -d "$HOME"/miniconda* ] || [ -d "$HOME"/anaconda* ]; then
echo "miniconda directory is found in your $HOME"
else
echo "anaconda/miniconda is not found in your $HOME"
fi
しかし、誰かが提案を持っている場合、ディレクトリを検索するときになぜ正規表現を渡すことができないのか知りたいのですが。