1. 程式人生 > >玩轉Bash腳本:選擇結構之case

玩轉Bash腳本:選擇結構之case

設置 pac tab 個數 trac char ... 依據 south

總第5篇

之前,我們談到了if。

這次我們來談還有一種選擇結構——case。

case與if

if用於選擇的條件,不是非常多的情況,假設選擇的條件太多。一系列的if。elif,。也是醉了。

沒錯,case在bash中的地位,和switch在C中的地位一樣。

可是使用方法可大有不同。

代碼塊

不論什麽語言都有代碼塊的概念,C語言中的花括號{ },python中的冒號和縮進。bash中的代碼塊風格不是非常統一。可是在選擇結構中是同樣的——反語。if結構使用if...fi標識一個代碼塊的作用域,而case也是用case...esac表示塊作用域的。。


基本結構

看樣例echo.sh:

#!/bin/bash
str="is good "
read -p "你喜歡什麽顏色:" color
case $color in
    red) echo -e "\e[1;31m$color $str \e[0m";;
    green) echo -e "\e[1;32m$color $str \e[0m";;
    yellow) echo -e "\e[1;33m$color $str \e[0m";;
    blue) echo -e "\e[1;34m$color $str \e[0m";;
    *) echo -e "\e[1;30m這是什麽顏色?\e[0m";;
esac
這段代碼,就是依據你的輸入來顯示不同顏色的文本。關於echo語句的寫法。這裏不細說。每句分別設置了不同的文本顏色。重點去看一下這個結構。

把變量color的值,依次和以下右括號中的值做比較。假設同樣,就運行後面的語句。

來執行一下
技術分享

兩個分號;;

註意每一個條件末尾都是兩個分號。

這非常好理解。就像C語言的switch裏面每一個case都常常會有一個break一樣。由於每一個條件滿足的時候,須要運行的語句可能不止一句。而在bash中多個語句在一行是用一個分號間隔的。這樣兩個分號就表示著語句結束。另外加一個空語句,也就是說要運行的語句都完畢了。

與c語言的switch不同的是,c語言中每一個條件(case語句)後面不一定都要有break。假設沒有break,則繼續運行以下的條件的語句。假設你想像c語言那樣多個條件共用一套語句,怎麽辦呢?

請繼續閱讀。

分號扭號;&

所謂扭號,就是And符號——&,我認為叫扭號更簡潔。。看一段C代碼:

#include<stdio.h>
int main(){
    char ans;
    printf("你喜歡編程麽:");
    scanf("%c",&ans);
    switch(ans){
        case 'y':
        case 'Y':printf("我也是\n");break;
        case 'n':
        case 'N':printf("sorry,跟你沒什麽好談的\n");break;
    }
}
也就是說。在C中,case後面假設不加break,那麽在運行完匹配的語句後,將接著運行。而無論以下的條件匹配不匹配,直到遇到break為止。這種語法。十分靈活。那麽bash中又怎樣實現呢?難道在末尾加一個分號?錯錯錯。答案是一個分號加一個扭號。

#!/bin/bash
read -p "你喜歡編程麽:(y/n):" ans
case $ans in
    y);&
    Y) echo "我也是";;
    n);&
    N) echo "sorry,跟你沒什麽好談的";;
esac

分號分號扭號;;&

除了 ;&結束語句以外。另一種是 ;;& 來結束語句的使用方法。

可是意義有所不同,;;&的使用方法是使得條件越來越精確

#!/bin/bash
read -p "請輸入一個區號:" num
case $num in
    *)echo -n "中國";;&
    03*)echo -n "河北省";;&
        ?

?10)echo "邯鄲市";; ?

?

11)echo "石家莊";; ??17)echo "滄州市";; 07*)echo -n "江西省";;& ??91)echo "南昌市";; ??92)echo "九江市";; ?

?97)echo "贛州市";; esac


關於通配符*和?,我們以下會講到。這裏,你僅僅須要知道。條件語句以 ;;& 結束的時候,程序運行到這裏不會停止,會繼續測試以下條件。假設滿足繼續運行,直到遇到 ;; 或esac

技術分享

註意。以上這兩種扭號的使用方法,是bash自己的 特性,對於其它shell,並不支持。

假設考慮移植性,就不要這樣寫了。

只用正規的兩個分號就能夠了。


右括號裏的模式

基本正則

)右括號。類似c語言中switch中的case。然而與之不同的是。Bash中的右括號中面,不僅支持完整的字符串(c語言中僅僅支持整型數據。包含int和char

,不支持字符串)還支持“模式”匹配。模式的概念,假設了解正則表達式。那麽就非常easy理解了。只是case語句中與正則表達式略有不同。貌似支持的並不完整。

  • *是匹配0個或多個不論什麽字符。

  • ?是匹配一個字符。

    能夠看做一個占位符。

  • [ ]表示一個範圍。

  • ( )枚舉字符串。可是須要轉義

#!/bin/bash
read -p "請輸入一個數字:" num
case $num in
    2*)echo "匹配2*";;&
    2?

)echo "匹配2?";;& [0-9])echo "匹配[0-9]";; esac

方括號表示範圍,你能夠使用[123]來匹配1或2或3。而不是123。也能夠使用[0-9]、[a-zA-Z]這種寫法。熟悉正則的同學。這些都不是問題。

註意我上面用到了 ;;& 也就是說在匹配了一個模式之後,不會停止,還會繼續向下運行。

運行效果:

技術分享

枚舉字符串

一般的寫法比方(123|456|789)匹配123,456,789這三個數。

可是由於case中右括號有特殊含義,所以進行了轉義。

然後我的寫法就是(123|456|789\)。可是這樣有個問題就是789無法得到匹配。123和456倒是能夠。我也是不明所以(見笑,知情者望告知)。

於是我又改了一版,最終匹配全然——(123|456|789|\)。

如今加上一句到剛才的腳本中——(123|456|789 \))echo "匹配(123|456|789|\)";;&

技術分享

POSIX字符類

一般的編程語言中的正則表達式。支持\w,\d這類的字符類(Character Classes)。而Unix-like系統上。支持的字符類是POSIX風格的。

見下表

描 述

擴 展

[:alnum:]

字母和數字字符

[0-9a-zA-Z]

[:alpha:]

(letters)字母字符(字母)

[a-zA-Z]

[:ascii:]

7位ASCII

[\x01-\x7F]

[:blank:]

水平空白符(空格、制表符)

[ \t]

[:cntrl:]

控制字符

[\x01-\x1F]

[:digit:]

數字

[0-9]

[:graph:]

用墨水打印的字符(非空格、非控制字符)

[^\x01-\x20]

[:lower:]

小寫字母

[a-z]

[:print:]

可打印字符(圖形類加空格和制表符)

[\t\x20-\xFF]

[:punct:]

隨意標點符號,如句點(.)和分號(;)

[-!"#$%&‘( )*+,./:;<=>?@[\\\]^_‘{|}~]

[:space:]

空白(換行、回車、制表符、空格、垂直制表符)

[\n\r\t \x0B]

[:upper:]

大寫字母

[A-Z]

[:xdigit:]

十六進制數字

[0-9a-fA-F]

這個表是從網友那裏復制的,原文《POSIX風格正則表達式

實際使用的時候,還要在這些字符類的方括號外面。再套一層方括號才行。

#!/bin/bash
read -p "請隨意輸入,能夠包括空格等空白符" ch
#echo $ch
case $ch in
    *[[:lower:]]*)echo lower;;&
    *[[:upper:]]*)echo upper;;&
    *[[:digit:]]*)echo digit;;&
    *[[:punct:]]*)echo punct;;&
    *[[:ascii:]]*)echo ascii;;&
    *[[:cntrl:]]*)echo cntrl;;&
    *[[:print:]]*)echo print;;&
    *[[:space:]]*)echo space;;&
    *[[:xdigit:]]*)echo xdigit;;&
    *[[:graph:]]*)echo graph;;&
    *[[:blank:]]*)echo blank;;&
    *[[:alnum:]]*)echo alnum;;&
    *[[:alpha:]]*)echo alpha;;&
esac

這個腳本。大家自己去測試吧。當然了有些字符(比方控制字符)貌似不好輸入。

這樣不好測試[:cntrl:]這個字符類,這裏我告訴您一下,ascii碼中27相應的控制字符就是ESC。

測試腳本的時候,能夠按一下ESC鍵。或者鍵入^[字符,也是一樣的。


本系列(玩轉Bash腳本)很多其它文章,請訪問:http://blog.csdn.net/column/details/wanbash.html

玩轉Bash腳本:選擇結構之case