単語に特定の文字が含まれている場合、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
* s77
output false)エラーを報告します。たとえば、次のようになります。
$'\x80abcde'
grep(正規表現の基本コマンド)が行うように(utf-8ロケールで):
$ echo $'\x80abcde' | grep '^.*$' # no output
$ (LANG=C; echo $'\x80abcde' | grep '^.*$')
�abcde