bashスクリプトで正規表現を使用してテストを否定するにはどうすればよいですか?


173

GNU bash(バージョン4.0.35(1)-release(x86_64-suse-linux-gnu))を使用して、正規表現によるテストを無効にしたいと思います。たとえば、PATH変数へのパスを条件付きで追加したいと思います。次のように、パスがまだない場合:

TEMP=/mnt/silo/bin
if [[ ${PATH} =~ ${TEMP} ]] ; then PATH=$PATH; else PATH=$PATH:$TEMP; fi
TEMP=/mnt/silo/Scripts:
if [[ ${PATH} =~ ${TEMP} ]] ; then PATH=$PATH; else PATH=$PATH:$TEMP; fi
TEMP=/mnt/silo/local/bin
if [[ ${PATH} =~ ${TEMP} ]] ; then PATH=$PATH; else PATH=$PATH:$TEMP; fi
export PATH

これを行う方法は100万通りあると私は確信していますが、(誤った)のように条件が何らかの形で否定できるかどうかを知りたいです。

TEMP=/mnt/silo/bin
if ![[ ${PATH} =~ ${TEMP} ]] ; then PATH=$PATH:$TEMP; fi
TEMP=/mnt/silo/Scripts:
if ![[ ${PATH} =~ ${TEMP} ]] ; then PATH=$PATH:$TEMP; fi
TEMP=/mnt/silo/local/bin
if ![[ ${PATH} =~ ${TEMP} ]] ; then PATH=$PATH:$TEMP; fi
export PATH

回答:


192

あなたはそれが正しい、ちょうど間にスペースを入れていた![[のようにif ! [[


14
大丈夫!perlの銀河系の特殊キャラクターの狂気を無事に回避したとき、私はbashスペース(配置)で迷っています!(Pythonのように腸を圧迫することに恐怖を感じます。)ありがとうございます。
David Rogers

126

かっこ内に感嘆符を付けることもできます。

if [[ ! $PATH =~ $temp ]]

しかし、パターンを固定して誤検知を減らす必要があります。

temp=/mnt/silo/bin
pattern="(^|:)${temp}(:|$)"
if [[ ! "${PATH}" =~ ${pattern} ]]

これは、最初または最後にコロンが前後に(または両方が)ある一致を探します。シェル変数との名前の衝突の可能性を減らすために、習慣として小文字または大/小文字混合の変数名を使用することをお勧めします。


ああ、アンカーについてのリマインダーをありがとう。小文字または混合変数名を使用するという考えは、bashの初心者には混乱を招きます。これまで見てきたアドバイスは大文字を使用することだからです。私はあなたが言っている点を理解していますが、クックブック(の私の理解)からの逸脱を快適に感じるのに十分なbashスクリプトの例は見ていません。
David Rogers

4
@anyoneisはこれを信頼してくれます。ユーザー定義の大文字の変数の使用は避けてください。bash内のすべての変数はで展開さ$れるため、目立つように大文字にする必要はありません。
SiegeX、2011年

if [[ ! $foo =~ bar ]]if ! [[ $foo =~ bar ]]if
CTodea


9

はい、SiegeXがすでに指摘したように、テストを無効にすることができます。

ただし、これには正規表現を使用しないでください。パスに特殊文字が含まれていると失敗する可能性があります。代わりにこれを試してください:

[[ ":$PATH:" != *":$1:"* ]]

(ソース)


1
このフォームを使用するもう1つの理由は、誤って部分文字列と一致しないためです(たとえば、「/ usr / bin」がすでにそこにあるため、「/ bin」をパスに追加できない)。
Gordon Davisson、2010

左側のコロンが私が望むアンカーをどのように与えてくれるか理解するのにしばらく時間がかかりました。検索する文字列に素材を追加してパターンを減らすという考えは、覚えておく価値があります。パス内の特殊文字が正規表現ソリューションを混乱させるが、bashパターンソリューションを妨害しない理由がわかりません。例を挙げてもらえますか?
David Rogers

これがすべてのケースで確実に機能するとは思いません。優れたIMHOでの正規表現一致
フェリペアルバレス

5

私はそのような場合に条件演算子を使わずにコードを単純化したいです:

TEMP=/mnt/silo/bin
[[ ${PATH} =~ ${TEMP} ]] || PATH=$PATH:$TEMP
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.