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


40

私はコードを持っています

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」になります。どうだった?問題を修正するには?


回答:


25

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

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

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

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


OPに当てはまりますが、移植性がないため、正解です。(これは提供された回答に対する批判ではなく、読者への警告です)。;-)
Cbhihe

28

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

#!/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]たとえば)、「一致」をトリガーする可能性が高くなります。

参照


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

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

使用することcase ... esacは、ポータブルな方法でパターンマッチを実行する最も簡単な方法の1つです。これは、(他の言語で「スイッチ」文として働くbashzshksh93もあなたは何をすることができますフォールスルーをさまざまな互換性のない方法で)。使用されるパターンは、標準のファイル名のグロビングパターンです。

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

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

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

testseq="_gen_"

そして*"$testseq"*、パターンとして使用します(文字列比較用)。


そのため、シェルは変数$ testseq_を探しますが、それを見つけずに空の文字列で置き換えます。
ヴィエステール

@Viestursそれが問題の核心です、はい。
クサラナナンダ

1
部分文字列の場合はそれがあるべき検索*"$testseq"*caseなどのための[[...]](あなたがglobsubstを有効にしない限りzshのを除く)
ステファンChazelas
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.