web-dev-qa-db-ja.com

文字列に部分文字列が含まれているかどうかをテストする

コードを持っています

file="JetConst_reco_allconst_4j2t.png"
if [[ $file == *_gen_* ]];
then
    echo "True"
else
    echo "False"
fi

fileに「gen」が含まれているかどうかをテストします。出力は「False」です。いいね!

問題は、「gen」を変数testseqに置き換えるときです。

file="JetConst_reco_allconst_4j2t.png"
testseq="gen"
if [[ $file == *_$testseq_* ]];
then
    echo "True"
else
    echo "False"
fi

これで出力は「True」になります。それはどうでしょうか?問題を解決するには?

43
Viesturs

$testseq変数は、次のいずれかの方法で補間する必要があります。

  • $file == *_"$testseq"_*(ここでは$testseqは固定文字列と見なされます)

  • $file == *_${testseq}_*(ここでは$testseqをパターンと見なしています)。

または、変数名の直後の_は、変数名の一部として使用されます(変数名の有効な文字です)。

28
RomanPerekhrest

正規表現の比較を行うには、=~演算子を使用します。

#!/bin/bash
file="JetConst_reco_allconst_4j2t.png"
testseq="gen"
if [[ $file =~ $testseq ]];
then
    echo "True"
else
    echo "False"
fi

このようにして、$fileの内容に$testseqがあるかどうかを比較します。

user@Host:~$ ./string.sh
False

testseq="Const"を変更した場合:

user@Host:~$ ./string.sh
True

ただし、$testseqのフィードには注意してください。上の文字列が何らかの形で正規表現を表している場合([0-9]など)、「一致」をトリガーする可能性が高くなります。

参照

32
user34720
file="JetConst_reco_allconst_4j2t.png"
testseq="gen"

case "$file" in
    *_"$testseq"_*) echo 'True'  ;;
    *)              echo 'False'
esac

case ... esacの使用は、移植可能な方法でパターン照合を実行する最も簡単な方法の1つです。他の言語では「switch」ステートメントとして機能します(bashzsh、およびksh93を使用すると、さまざまな非互換でfall-throughを実行することもできます)方法)。使用されるパターンは、標準のファイル名グロビングパターンです。

発生している問題は、_が変数名の有効な文字であることによるものです。したがって、シェルは*_$testseq_*を "*_の後に変数$testseq_の値と*"が続くものとして認識します。変数$testseq_は定義されていないため、空の文字列に展開され、最終的に*_*になり、これは明らかに$fileの値と一致します。 $fileのファイル名に少なくとも1つのアンダースコアが含まれている限り、Trueを取得することが期待できます。

変数の名前を適切に区切るには、展開の前後に"..."を使用します:*_"$testseq"_*。これは、変数の値を文字列として使用します。変数の値をパターンとして使用する場合は、代わりに*_${testseq}_*を使用します。

別の簡単な修正は、アンダースコアを$testseqの値に含めることです:

testseq="_gen_"

次に、パターンとして(文字列比較の場合)*"$testseq"*を使用します。

21
Kusalananda

文字列に部分文字列が含まれているかどうかをテストするポータブルな方法については、次を使用します。

file="JetConst_reco_allconst_4j2t.png";       testseq="gen"

[ "${file##*$testseq*}" ] || echo True Substring is present

または"${file##*"$testseq"*}"は、testseq内のグロブ文字の解釈を回避します。

2
Isaac