Saya mencoba menggunakan variabel yang terdiri dari string berbeda yang dipisahkan dengan |
sebagai case
tes pernyataan. Sebagai contoh:
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 menjalankan bagian pertama dari case
pernyataan itu. 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. 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 dalam bash. Apakah mungkin dan, jika ya, bagaimana?
bash
shell-script
case
terdon
sumber
sumber
eval
, melepaskan $ pilihan, parens, asterisk, titik koma, dan baris baru. Jelek, tapi "berhasil".read
sedikit menghentikan saya. menurut pendapat saya, validasi input pengguna, yang memang seperti ini,case
pola seharusnya tidak berada di bagian atas daftar evaluasi, dan lebih baik dipangkas ke*
pola default sehingga satu-satunya hasil yang mencapai di sana dijamin dapat diterima. tetap saja, karena masalahnya adalah urutan parse / ekspansi, maka evaluasi kedua bisa menjadi apa yang diperlukan.Jawaban:
Manual bash menyatakan:
Tidak ada «Perluasan jalur»
Jadi: suatu pola TIDAK diperluas dengan «ekspansi Pathname».
Karenanya: suatu pola TIDAK dapat mengandung "|" dalam. Hanya: dua pola dapat digabungkan dengan "|".
Ini bekerja:
Menggunakan «Extended Globbing»
Namun,
word
dicocokkan denganpattern
menggunakan aturan «Pathname Expansion».Dan «Extended Globbing» di sini , di sini dan, di sini memungkinkan penggunaan pola bolak-balik ("|").
Ini juga berfungsi:
Konten string
Skrip pengujian berikutnya menunjukkan bahwa pola yang cocok dengan semua baris yang berisi salah satu
foo
atau dibar
mana saja adalah'*$(foo|bar)*'
atau dua variabel$s1=*foo*
dan$s2=*bar*
Skrip pengujian:
sumber
Anda dapat menggunakan
extglob
opsi:sumber
@(foo|bar)
istimewa dibandingkan denganfoo|bar
? Keduanya adalah pola yang valid yang berfungsi sama saat diketik secara harfiah.|
bukan bagian dari pola dalamfoo|bar
, itu bagian dari sintakscase
pernyataan untuk memungkinkan beberapa pola dalam satu klausa.|
adalah bagian dari pola yang diperluas.Anda memerlukan dua variabel untuk
case
karena atau|
pipa diurai sebelum pola diperluas.Pola Shell dalam variabel ditangani secara berbeda ketika dikutip atau tidak dikutip juga:
sumber
Jika Anda ingin bekerja di dash-kompatibel, Anda bisa menulis:
Penjelasan: awk digunakan untuk membagi "string" dan menguji setiap bagian secara terpisah. Jika "pilihan" cocok dengan bagian yang sedang diuji p [i], perintah-awk akan diakhiri dengan "keluar" di baris 11. Untuk uji coba sendiri, "kasing" shell digunakan (dalam panggilan 'sistem') , seperti yang ditanyakan oleh terdon. Hal ini membuat kemungkinan untuk memodifikasi "string" pengujian yang dimaksud misalnya menjadi "foo * | bar" agar sesuai dengan "foooo" ("pola pencarian"), sesuai dengan "case" shell yang memungkinkan. Jika sebaliknya Anda lebih suka ekspresi reguler, Anda bisa menghilangkan "sistem" -call dan menggunakan awk "~" atau "cocok" sebagai gantinya.
sumber