Saya mencoba menggunakan variabel yang terdiri dari string berbeda yang dipisahkan dengan |
sebagai case
tes pernyataan. Misalnya:
string=""foo"|"bar""
read choice
case $choice in
$string)
echo "You chose $choice";;
*)
echo "Bad choice!";;
esac
Saya ingin dapat mengetik foo
atau bar
dan jalankan bagian pertama dari case
penyataan. Namun, keduanya foo
dan bar
bawa saya ke yang kedua:
$ foo.sh
foo
Bad choice!
$ foo.sh
bar
Bad choice!
Menggunakan "$string"
bukannya $string
tidak ada bedanya. Juga tidak menggunakan string="foo|bar"
.
Saya tahu saya bisa melakukannya dengan cara ini:
case $choice in
"foo"|"bar")
echo "You chose $choice";;
*)
echo "Bad choice!";;
esac
Saya dapat memikirkan berbagai solusi tetapi saya ingin tahu apakah mungkin menggunakan variabel sebagai case
kondisi di bash. Apakah mungkin dan, jika demikian, bagaimana caranya?
Jawaban yang Diterima:
Manual bash menyatakan:
kata kasus dalam daftar [ [(] pola [ | pola ] … );; ] … esac
Setiap pola yang diperiksa diekspansi menggunakan ekspansi tilde, ekspansi parameter dan variabel, substitusi aritmatika, substitusi perintah, dan substitusi proses.
Tidak ada «Perluasan nama jalur»
Jadi:sebuah pola TIDAK diperluas dengan «Perluasan nama jalur».
Oleh karena itu:suatu pola TIDAK boleh mengandung “|” dalam. Hanya:dua pola dapat digabungkan dengan “|”.
Ini berfungsi:
s1="foo"; s2="bar" # or even s1="*foo*"; s2="*bar*"
read choice
case $choice in
$s1|$s2 ) echo "Two val choice $choice"; ;; # not "$s1"|"$s2"
* ) echo "A Bad choice! $choice"; ;;
esac
Menggunakan « Globbing Diperpanjang »
Namun, word
dicocokkan dengan pattern
menggunakan aturan « Ekspansi Pathname ».
Dan « Extended Globbing » di sini, di sini dan, di sini memungkinkan penggunaan pola bergantian (“|”).
Ini juga berfungsi:
shopt -s extglob
string='@(foo|bar)'
read choice
case $choice in
$string ) printf 'String choice %-20s' "$choice"; ;;&
$s1|$s2 ) printf 'Two val choice %-20s' "$choice"; ;;
*) printf 'A Bad choice! %-20s' "$choice"; ;;
esac
echo
Konten string
Skrip pengujian berikutnya menunjukkan bahwa pola yang cocok dengan semua baris yang berisi foo
atau bar
di mana saja adalah '*$(foo|bar)*'
atau dua variabel $s1=*foo*
dan $s2=*bar*
Skrip pengujian:
shopt -s extglob # comment out this line to test unset extglob.
shopt -p extglob
s1="*foo*"; s2="*bar*"
string="*foo*"
string="*foo*|*bar*"
string='@(*foo*|*bar)'
string='*@(foo|bar)*'
printf "%sn" "$string"
while IFS= read -r choice; do
case $choice in
"$s1"|"$s2" ) printf 'A first choice %-20s' "$choice"; ;;&
$string ) printf 'String choice %-20s' "$choice"; ;;&
$s1|$s2 ) printf 'Two val choice %-20s' "$choice"; ;;
*) printf 'A Bad choice! %-20s' "$choice"; ;;
esac
echo
done <<-_several_strings_
f
b
foo
bar
*foo*
*foo*|*bar*
"foo"
"foo"
afooline
onebarvalue
now foo with spaces
_several_strings_