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

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

一般的なシェル(bash、dash、kornshell)で実行できるコマンドがあるかどうかを尋ねたかったです。line変数にパスの一部が含まれていることを確認する必要があります。

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

答え1

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

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

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

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

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ファイル名の生成に影響されません。引用符のない拡張子は分割されたり、ワイルドカードとして指定されたりしません。
    • ただし、ここで引用されていない拡張はリテラル文字列ではなくパターンとして解釈される可能性があるため、拡張は引用の有無に応じて複数の意味を持つことがあります。
    • 文字通り解釈されるパターン文字を参照することが重要であるかのように、文字通り解釈されるべきパターンで使用されるすべての変数を引用することが重要です。
    • たとえば、$PWDaが含まれていて引用符がない場合、検索するリテラルではなくパターンオブジェクト*として解釈されます。*

答え2

はい、最新バージョンのbashでは次のことができます。

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

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

正規表現は変数です$line 終わるそして$PWD$PWDの任意の場所で一致するものを確認するには、$line以下を削除してください$

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

答え3

シェル置換で条件付き行を使用できます。

if [ "$line" != "${line#*$PWD}" ] ; then
    echo "Path found in line"
fi

これは、$line から $PWD 値を削除するためにシェル・パラメータ拡張を使用して行われます。文字列が一致しない場合、削除は成功し、$ PWD値はその行にあります(つまり、$lineに$ PWDが含まれています)。

しかし、パスマッチングを行う場合、これは意味的に望ましくないかもしれません。たとえば、 $PWD が "/bin" で $line が "/sbin:/usr/bin" の場合、/usr/bin に対して誤った肯定一致が発生します ("/bin" が一致するため)。

これはPOSIXと互換性があり、すべてのシェルで動作します。

関連情報