コードがあります
file="JetConst_reco_allconst_4j2t.png"
if [[ $file == *_gen_* ]];
then
echo "True"
else
echo "False"
fi
file
「gen」が含まれているかどうかをテストします。出力は「偽」です。いいね!
問題は、「gen」を変数に置き換えるときですtestseq
。
file="JetConst_reco_allconst_4j2t.png"
testseq="gen"
if [[ $file == *_$testseq_* ]];
then
echo "True"
else
echo "False"
fi
これで出力は「True」です。どうやって?この問題をどのように解決しますか?
答え1
演算子を使用した正規表現の比較=~
:
#!/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]
「一致」がトリガーされる可能性が高くなります。
引用する:
答え2
$testseq
変数を挿入するには、次のいずれかの方法を使用する必要があります。
$file == *_"$testseq"_*
(ここでは$testseq
固定文字列とみなされます)$file == *_${testseq}_*
(ここでは$testseq
パターンと見なされます)。
または、_
変数名の直後の文字は変数名の一部と見なされます(変数名で有効な文字です)。
答え3
file="JetConst_reco_allconst_4j2t.png"
testseq="gen"
case "$file" in
*_"$testseq"_*) echo 'True' ;;
*) echo 'False'
esac
を使用することは、case ... esac
移植可能な方法でパターンマッチングを実行する最も簡単な方法の1つです。他の言語では、「スイッチ」ステートメントとして使用されます(bash
、、、、および次のこともできます。zsh
ksh93
落ちるさまざまな互換性のない方法で)。使用されるパターンは、標準ファイル名のワイルドカードパターンです。
発生した問題は、_
変数名の文字が有効であるために発生します。したがって、シェルは*_$testseq_*
「*_
変数値の合計$testseq_
」を表示します*
。変数は$testseq_
定義されていないため、空の文字列に展開され、で終わります*_*
。これは明らかに$file
持っている値と一致します。結果True
ファイル名に$file
少なくとも1つのアンダースコアが含まれると予想できます。
変数名を適切に区切るには、"..."
拡張子を使用してください*_"$testseq"_*
。変数の値を文字列として使用します。変数の値を次のように使用したいと思います。模様、*_${testseq}_*
代わりに使用してください。
別のクイック修正は、値にアンダースコアを含めることです$testseq
。
testseq="_gen_"
その後、パターンとして使用されます*"$testseq"*
(文字列比較用)。
答え4
文字列に部分文字列が含まれているかどうかをテストする移植可能な方法の場合は、次のようにします。
file="JetConst_reco_allconst_4j2t.png"; testseq="gen"
[ "${file##*$testseq*}" ] || echo True Substring is present
または"${file##*"$testseq"*}"
説明を避けてくださいtestseq
。