Saya punya kodenya
file="JetConst_reco_allconst_4j2t.png"
if [[ $file == *_gen_* ]];
then
echo "True"
else
echo "False"
fi
Saya menguji apakah file
mengandung "gen". Outputnya "Salah". Bagus!
Masalahnya adalah ketika saya mengganti "gen" dengan variabel testseq
:
file="JetConst_reco_allconst_4j2t.png"
testseq="gen"
if [[ $file == *_$testseq_* ]];
then
echo "True"
else
echo "False"
fi
Sekarang hasilnya adalah "Benar". Bagaimana mungkin? Bagaimana cara mengatasi masalah?
shell-script
variable
string
control-flow
Viesturs
sumber
sumber
Jawaban:
Anda perlu menginterpolasi
$testseq
variabel dengan salah satu cara berikut:$file == *_"$testseq"_*
(di sini$testseq
dianggap sebagai string tetap)$file == *_${testseq}_*
(di sini$testseq
dianggap sebagai pola).Atau
_
segera setelah nama variabel akan diambil sebagai bagian dari nama variabel (itu adalah karakter yang valid dalam nama variabel).sumber
Gunakan
=~
operator untuk membuat perbandingan ekspresi reguler:Dengan cara ini, ia akan membandingkan jika
$file
ada$testseq
pada isinya.Jika saya berubah
testseq="Const"
:Tapi, berhati-hatilah dengan apa yang Anda makan
$testseq
. Jika string di atasnya menunjukkan beberapa regex (seperti[0-9]
misalnya), ada lebih banyak kesempatan untuk memicu "kecocokan".Referensi :
sumber
Menggunakan
case ... esac
adalah salah satu cara paling sederhana untuk melakukan pencocokan pola dengan cara portabel. Ia bekerja sebagai "switch" pernyataan dalam bahasa lain (bash
,zsh
, danksh93
juga memungkinkan Anda untuk melakukan jatuh-melalui berbagai cara yang tidak kompatibel). Pola yang digunakan adalah pola globbing nama file standar.Masalah yang Anda hadapi disebabkan oleh fakta bahwa
_
karakter yang valid dalam nama variabel. Shell dengan demikian akan melihat*_$testseq_*
"*_
diikuti oleh nilai variabel$testseq_
dan*
". Variabel$testseq_
tidak terdefinisi, sehingga akan diperluas ke string kosong, dan Anda berakhir dengan*_*
, yang jelas cocok dengan$file
nilai yang Anda miliki. Anda mungkin berharap mendapatkanTrue
selama nama file dalam$file
mengandung setidaknya satu garis bawah.Untuk benar membatasi nama variabel, penggunaan
"..."
sekitar ekspansi:*_"$testseq"_*
. Ini akan menggunakan nilai variabel sebagai string. Jika Anda ingin menggunakan nilai variabel sebagai pola , gunakan*_${testseq}_*
saja.Perbaikan cepat lainnya adalah dengan memasukkan garis bawah dalam nilai
$testseq
:dan kemudian gunakan saja
*"$testseq"*
sebagai pola (untuk perbandingan string).sumber
*"$testseq"*
untukcase
seperti untuk[[...]]
(kecuali untuk zsh kecuali jika Anda mengaktifkan globsubst)