変数に、長さが異なるテキストの文字列を満たそうとする。重要な文字列の部分は、最初の数文字です。
var1=hello
if [ $var1 == hello ]; then
echo success
fi
または
var1=hello
if [ $var1 == h*o ]; then
echo success
fi
出力:成功
しかし、私は最初の3文字程度を気にしているので、これは論理的に聞こえますが機能していません。
var1=hello
if [ $var1 == hel* ]; then
echo success
fi
出力:-bash:[:引数が多すぎます
最初の数文字しか気にしないので、次のことができます。
var1=hello
if [ ${var1:0:3} == hel ]; then
echo success
fi
それはうまくいくでしょうが、私はなぜそのエラーが発生するのかの説明と、考えられるより良い書かれた解決策を探しています。
if
で*
を使用すると、ファイル名が拡張されます。したがって、最初のインスタンスでは、h*o
はおそらく現在のディレクトリ内のファイルと一致しているため、テストに合格しました。
hel*
は複数のファイルに一致したため、if
コマンドの引数が多すぎます。
if [[ $var1 == hel* ]]; then
をお試しください
二重括弧はテストを正規表現に変換し、*
ワイルドカードは期待どおりに機能します。
[
*は、grep
、find
、またはcat
と同様の通常のコマンドです。 /bin
で見つけることができるはずです。別のプログラムであるため、シェルは引数を[
を渡す前に通常の展開セットを実行します。
すでに述べたように、テストで*
を使用しているため、グロブ拡張が発生しています。 'hel*'
などの引用符を使用しても、[
はパターンをサポートしていないため、これはおそらく期待どおりに機能しません。 h*o
が機能している場合、現在のディレクトリにhello
という名前のファイルがあり、そのパターンに一致する他のファイルがないことが原因である可能性があります。 hello
ファイルがなくても機能する場合は、実装がおかしい可能性があり、スクリプトが他のシステムで失敗する可能性があります。
必要に応じて、いくつかのオプションがあります。 Bash、Zsh、およびその他の一部のシェルには、[[
が組み込まれています。組み込みであるため、グロブ拡張の回避など、引数に特別な扱いを与えることができます。さらに、パターンマッチングを実行できます。試す
var1=hello
if [[ "$var1" = hel* ]]; then
echo success
fi
また、パターンを囲む引用符がないことに注意してください。引用符がない場合、hel*
は[[
によってパターンとして扱われ、引用符(単一または二重)があると、"hel*"
は文字どおりに扱われます。
[[
のないシェルなど、より広い互換性が必要な場合は、grepを使用できます。
var1=hello
if echo "$var1" | grep -qe 'hel.*' ; then
echo success
fi
ここでは[
または[[
は不要ですが、'hel.*'
を囲む引用符は必要です。
*一部のシェルには実際に[
が組み込まれていますが、これは効率化のためです。それはすべきシェルの通常の「マングリング」の対象となる引数を持つことを含め、個別の実行可能ファイルと同じように動作します。
組み込みのbash正規表現を使用せずに正規表現をハックするために使用するトリックがあります。例は#2です。これが機能する方法は、grepが何にも一致しない場合、出力を返さない(つまり、存在しない文字列)ことです。したがって、2つのテストがあります。-zは「null文字列」を意味し、-nは「データあり」を意味します。
if [ -n "`echo $var1 | grep -e 'h.*o'`" ] ; then
echo 'water found'
fi
これはどう ?
if [["$ var1" == "hel" *]]
文字列の比較を行う際は、引用符の外にワイルドカードを付けます。