web-dev-qa-db-ja.com

文字列内のパターンを見つけるシェルテスト

一般的なシェル(bash、dash、kornshell)で機能するコマンドがあるかどうかを確認したいだけですか? line変数にパスの一部が含まれているかどうかをチェックすることになっています。

if [[ $line =~ "$PWD"$ ]] ;then
8
applenic

はい、bashの最近のバージョンはこれを行うことができます:

$ pwd
/home/terdon
$ line="I'm in /home/terdon"
$ [[ "$line" =~ "$PWD"$ ]] && echo yes
yes

同じ構文がzshとkshで機能しますが、ダッシュでは機能しません。私の知る限り、dashにはそのような機能はありません。

正規表現は変数$lineends$PWDであるかどうかをチェックしていることに注意してください。 $PWD$lineのどこかに一致するかどうかを確認するには、$を削除します。

$ line="I'm in /home/terdon, are you?"
$ [[ "$line" =~ "$PWD" ]] && echo yes
yes
4
terdon

POSIX互換シェルでは、次のことができます。

case $line in (*"$PWD"*)
#    whatever your then block had
;;esac

これは、bashdash、および名前を付けることができる他のほぼすべてのシェルで機能します。

また、複数の可能性を簡単に処理するためにも使用できます。例えば:

case $line in 
(*"$PWD"*)
    echo \$PWD match\!
;;
(*"$OLDPWD"*)
    echo \$OLDPWD match\!
;;
(*)
    ! echo no match\!
;;esac

代替を使用することもできます:

case $line in (*"$PWD"*|*"$OLDPWD"*)
    echo '$OLDPWD|$PWD match!'
;;esac

上記の引用の使用に注意してください。

  1. case $line ...
    • caseステートメントのオブジェクトは、$IFSで分割されることも、ファイル名genのパターンとして使用されることもありません。これは、[[テストの左側の引数が処理される方法に似ています。
  2. (*"$PWD"*)
    • ここでも、シェル拡張は$IFSまたはファイル名生成の対象ではありません。引用符で囲まれていない拡張は分割もグロブも行われません。
    • ただし、ここで引用符で囲まれていない展開は、リテラル文字列ではなくパターンとして解釈される可能性があるため、展開は、引用符で囲まれているかどうかによって、複数のことを意味する場合があります。
    • 文字どおりに解釈したいパターン文字を引用するのと同じ方法で、文字どおりに解釈すべきパターンで使用される変数を引用することが重要です。
    • たとえば、$PWD*が含まれていて、引用符で囲まれていない場合、検索されるリテラル*ではなく、パターンオブジェクトとして解釈されます。
14
mikeserv