IF文は、単語に特定の文字が含まれている場合はtrueを返します。

IF文は、単語に特定の文字が含まれている場合はtrueを返します。

単語に特定の文字が含まれている場合、trueを返すにはif文が必要です。たとえば、

var="information"
if [ $var contain "i" ]; then
....
else
...
fi

答え1

switchまたはcaseこれに似たものを使うのはどうですか?

#!/bin/sh

v="information"
case $v in
    *f*)
        echo "found \"f\" in ${v}";;
    *)
        echo "no match found in ${v}"
esac
exit

針が変数に保存されている場合は、パターンと見なされないように引用することが重要です。

case $haystack in
  *"$needle"*) echo match
esac

それがなければ、例えばどんな$needle場合*でも?一致します。大きな干し草の山(それぞれ空でない干し草の山)

とにかく、必ずしも$needle単一文字である必要はありません。どの文字列でも機能します。

多くのシェルでは、空でないバイトシーケンスでも機能します。有効な文字を形成しなくても、すべてのバイトが文字に分割されるわけではありません。たとえば、é一部の実装では、UTF-8(0xc3 0xa9)でエンコードされた文字列に0xc3バイトを見つけることができません。逆に、ロケールのエンコーディングiが0x3 0x69(ASCIIなどの0x69)エンコーディングを持つBIG5-HKSCSの場合、一部のシェルが内部的に見つかる可能性があります。ξξi

答え2

Bashの[[ ... ]]テストはパターンマッチングと正規表現を理解します。

==and演算子を使用している場合は、!=演算子の右側の文字列をパターンとしてパターンマッチングを実行します。演算子を使用する場合、=~演算子の右側の文字列は正規表現で一致します。

だから:

s=information
if [[ $s = *i* ]] ; then echo has i ; fi

引用符付き文字列は文字通り使用されます。

if [[ $s = "*i*" ]] ; then echo is i between two asterisks ; fi

正規表現を知っています

if [[ $s =~ ^.*i.*$ ]] ; then echo has i ; fi

通常どおり文字列全体を埋めない一致も必要です。

if [[ $s =~ i ]] ; then echo has i ; fi

答え3

この[[ ... ]]場合、比較の右側がパターンとして機能します。

if [[ $var == *i* ]] ; then

答え4

古い(そしてかなり移植性に優れた)方法は、ケースステートメントを使用することです:

var="information"
case $var in
     *i*) echo "An 'i' was found in $var";;
     * )  echo "There is no 'i' in $var";;
esac

一行機能で:

a="information"   b="i"

one(){ case $a in (*${b}*) true;; (*) false;; esac; }

そして:

if one; then 
    echo "Found %b in $a"; 
else
    echo "The character '$b' was not found in the string '$a'"
fi

同じテストを実行する他の効果的な方法は次のとおりです。

two(){ [[  $a ==   *"$b"*      ]] ; }   # Using a pattern match.
t33(){ [[  $a =~    "$b"       ]] ; }   # Extended Regex (ERE) match.
f44(){ [[  $a =~ ^.*"$b".*$    ]] ; }   # Using a ERE with limits.
f55(){ [[  ${a//[!"${b}"]}     ]] ; }   # Removing all non-matching chars.
six(){ [ ! "$a" = "${a%"$b"*}"  ] ; }   # Using char removal. 
s77(){ [[  $a =~ ^.*$          ]] ; }   # Testing if string is valid.

すべての関数は有効な文字列を使用します。
10、100、1000、...、1000000(百万)文字の文字列の場合、各関数のタイミングは次のとおりです。

        Number of characters in the string.
        10     100    1000    10000   100000  1000000
one  0.024m  0.036m  0.047m   0.207m   2.117m  25.363m
two  0.028m  0.030m  0.043m   0.179m   2.081m  25.337m
t33  0.044m  0.041m  0.053m   0.151m   1.757m  22.695m
f44  0.064m  0.075m  0.241m   1.864m  19.489m 198.488m
f55  0.055m  0.182m  5.275m 421.886m
six  0.043m  0.057m  0.297m  13.987m
s77  0.056m  0.061m  0.154m   1.201m  12.749m 134.774m

文字数は繰り返される文字で構成されます。
テストする文字列は次のように構成されています。

a="$1$(repeat "$2" 10**$k)$3"

スクリプト名は次のとおりです。

$ ./script start a ending 

f55(約)1000文字を超える文字列を処理すると、この関数は非常に遅くなります。six(約)10000(10k)文字を超える文字列でも同じ現象が発生します。

短い文字列の場合は関数がtwo速く、t33長い文字列の場合(regex)が最善です。

機能t33~s77は、以下のように実行した場合の実行時間を変更する。

$ LANG=C ./script

すべてが速くなります。

興味深いことに、テストされた文字列が無効なUTF-8文字列の場合、関数はf44* s77output false)エラーを報告します。たとえば、次のようになります。

$'\x80abcde'

grep(正規表現の基本コマンド)が行うように(utf-8ロケールで):

$ echo $'\x80abcde' | grep '^.*$'       # no output

$ (LANG=C; echo $'\x80abcde' | grep '^.*$') 
�abcde

関連情報