IF文では、Linux Bash OR演算子が期待どおりに機能しません。

IF文では、Linux Bash OR演算子が期待どおりに機能しません。

異なる命名規則を持つ2つのホストがあるとします。

ab_01そしてab_cd

私は彼らの命名規則が特定の基準を満たしていることを確認したいと思います。

だからテストするための簡単なスクリプトを書いた。

wolf@linux:~$ host='ab_01'

wolf@linux:~$ if [[ $host =~ [a-z][a-z]_[a-z][a-z] ]]; then echo True; else echo False; fi
False

wolf@linux:~$ if [[ $host =~ [a-z][a-z]_[0-9][0-9] ]]; then echo True; else echo False; fi
True

効果がある!

次のステップは、これら2つの正規表現をシェルのOR演算子と組み合わせることです。||

if [[ $host =~ [a-z][a-z]_[a-z][a-z] || $host =~ [a-z][a-z]_[0-9][0-9] ]];
then
    echo True
else
    echo False
fi

テストしてみましょう

wolf@linux:~$ echo $host
ab_01
wolf@linux:~$ if [[ $host =~ [a-z][a-z]_[a-z][a-z] || $host =~ [a-z][a-z]_[0-9][0-9] ]];
> then
>     echo True
> else
>     echo False
> fi
True
wolf@linux:~$

それとab_01で動作しますab_cd

ただし、ホスト名にさらに文字を追加した場合はFalseにする必要がありますが、それでもTrueが表示されます。

以下を使ってhost='ab_0123'テストしましょう。host='ab_cdef'

wolf@linux:~$ host='ab_0123'
wolf@linux:~$ if [[ $host =~ [a-z][a-z]_[a-z][a-z] || $host =~ [a-z][a-z]_[0-9][0-9] ]];
> then
>     echo True
> else
>     echo False
> fi
True
wolf@linux:~$ 

別のテストでは、Falseの代わりにTrueが表示されます。

wolf@linux:~$ host='ab_cdef'
wolf@linux:~$ if [[ $host =~ [a-z][a-z]_[a-z][a-z] || $host =~ [a-z][a-z]_[0-9][0-9] ]];
> then
>     echo True
> else
>     echo False
> fi
True
wolf@linux:~$ 

このコードには何の問題があり、どのように解決しますか?

答え1

パターンマッチングとは異なり、正規表現マッチングは文字列の先頭/末尾に固定されません。どこかに文字列で十分です。 (「一致」というよりは「検索」に近いので、いくつかのPython関数名が違いを生むと思いますab_cdefab_cd

^そして、以下を使用してパターンを明示的に固定する必要があります$

$ if [[ foobar =~ o ]]; then echo yes; else echo no; fi
yes
$ if [[ foobar =~ ^o$ ]]; then echo yes; else echo no; fi
no

||正規表現に代替項目を入れることもできます。

re='^[a-z][a-z]_([0-9][0-9]|[a-z][a-z])$'
if [[ $host =~ $re ]]; then ...

(またはより快適な正規表現が許可されます:ab_a0^[a-z][a-z]_[0-9a-z][0-9a-z]$

関連情報