2011-04-06 39 views
98

Tôi đang tìm cú pháp chính xác của câu lệnh switch với các trường hợp fallthrough trong Bash (lý tưởng không phân biệt chữ hoa chữ thường). Trong PHP tôi sẽ chương trình nó thích:Chuyển đổi trường hợp với fallthrough?

switch($c) { 
    case 1: 
     do_this(); 
     break; 
    case 2: 
    case 3: 
     do_what_you_are_supposed_to_do(); 
     break; 
    default: 
     do_nothing(); 
} 

Tôi muốn cùng trong Bash:

case "$C" in 
    "1") 
     do_this() 
     ;; 
    "2") 
    "3") 
     do_what_you_are_supposed_to_do() 
     ;; 
    *) 
     do_nothing(); 
     ;; 
esac 

này bằng cách nào đó không hoạt động: chức năng do_what_you_are_supposed_to_do() nên bị sa thải khi $ C là 2 hoặc 3.

+2

Không sử dụng chức năng cuộc gọi với Parens !!! Vì bạn có thể định nghĩa một hàm trong bash bằng cách sử dụng 'function fname {echo" Inside fname "; trả về 0; } 'hoặc' fname() {echo "bên trong fname"; trả về 0; } 'đặt parens trên một cuộc gọi hàm có thể trông giống như đó là một hàm defintion. Các hàm nên được gọi như bất kỳ chương trình dòng lệnh nào khác như 'mv',' cp', 'rsync',' ls', 'cd', v.v ... Trong trường hợp này, chúng ta gọi fname như sau:' fname $ ARGS' . –

+0

'do_nothing()' có phải là tuyên bố SKIP không? Sử dụng ':'. – sjas

Trả lời

176

Sử dụng thanh dọc (|) cho "hoặc".

case "$C" in 
"1") 
    do_this() 
    ;; 
"2" | "3") 
    do_what_you_are_supposed_to_do() 
    ;; 
*) 
    do_nothing() 
    ;; 
esac 
+19

Hoặc trong trường hợp đơn giản này, một lớp nhân vật '[23])' – SiegeX

22
  • Không sử dụng () đằng sau tên hàm trong bash trừ khi bạn muốn định nghĩa chúng.
  • sử dụng [23] trong trường hợp để phù hợp với 2 hoặc 3
  • trường hợp chuỗi tĩnh nên được bao bọc bởi '' thay vì ""

Nếu kèm theo trong "", người phiên dịch (không cần thiết) cố gắng mở rộng các biến thể trong các giá trị trước khi kết hợp.

case "$C" in 
'1') 
    do_this 
    ;; 
[23]) 
    do_what_you_are_supposed_to_do 
    ;; 
*) 
    do_nothing 
    ;; 
esac 

Đối với trường hợp hợp không nhạy cảm, bạn có thể sử dụng các lớp nhân vật (như [23]):

case "$C" in 

# will match C='Abra' and C='abra' 
[Aa]'bra') 
    do_mysterious_things 
    ;; 

# will match all letter cases at any char like `abra`, `ABRA` or `AbRa` 
[Aa][Bb][Rr][Aa]) 
    do_wild_mysterious_things 
    ;; 

esac 

Nhưng abra không trúng bất cứ lúc nào bởi vì nó sẽ được xuất hiện bởi trường hợp đầu tiên.

Nếu cần, bạn có thể bỏ qua ;; trong trường hợp đầu tiên để tiếp tục thử nghiệm cho các kết quả phù hợp trong các trường hợp sau. (;; nhảy đến esac)

+0

Bạn cũng có thể chuyển đổi C thành chữ thường "$ {C ,,}" in' nếu trường hợp không quan trọng – Sprinterfreak

+0

Điều gì sẽ xảy ra nếu bạn bỏ qua ';;'? Bạn không phải sử dụng '; &' cho fallthrough? – HelloGoodbye

+0

Tôi nhận được lỗi cú pháp nếu tôi bỏ qua ';;' Tôi cần sử dụng ';; &' nếu tôi muốn tiếp tục thử nghiệm. – Jasen

45

gần đây bash phiên bản cho phép sụp đổ qua bằng cách sử dụng ;& thay cho ;;: họ cũng cho phép nối lại các kiểm tra trường hợp bằng cách sử dụng ;;& đó.

for n in 4 14 24 34 
do 
    echo -n "$n = " 
    case "$n" in 
    3?) 
    echo -n thirty- 
    ;;& #resume (to find ?4 later) 
    "24") 
    echo -n twenty- 
    ;& #fallthru 
    "4" | ?4) 
    echo -n four 
    ;;& # resume (to find teen where needed) 
    "14") 
    echo -n teen 
    esac 
    echo 
done 

đầu ra mẫu

4 = four 
14 = fourteen 
24 = twenty-four 
34 = thirty-four 
8

Hãy thử điều này:

case $VAR in 
normal) 
    echo "This doesn't do fallthrough" 
    ;; 
special) 
    echo -n "This does " 
    ;& 
fallthrough) 
    echo "fall-through" 
    ;; 
esac 
+0

là một mẹo rất hữu ích. Ít nhất là đối với Bash 4.3.11. Tôi đã không bận tâm để thử nó trên bất kỳ những người khác. – Daniel

+0

Cảm ơn bạn cảm ơn bạn cảm ơn bạn! –

+1

Lưu ý: Tính năng này không hoạt động đối với bash 3.2, vẫn là bash mặc định trong macOS. –

Các vấn đề liên quan