zoukankan      html  css  js  c++  java
  • 玩转Bash脚本:选择结构之case

    总第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("我也是
    ");break;
            case 'n':
            case 'N':printf("sorry,跟你没什么好谈的
    ");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:]

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

    [ ]

    [:cntrl:]

    控制字符

    [x01-x1F]

    [:digit:]

    数字

    [0-9]

    [:graph:]

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

    [^x01-x20]

    [:lower:]

    小写字母

    [a-z]

    [:print:]

    可打印字符(图形类加空格和制表符)

    [ x20-xFF]

    [:punct:]

    随意标点符号,如句点(.)和分号(;)

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

    [:space:]

    空白(换行、回车、制表符、空格、垂直制表符)

    [ 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

  • 相关阅读:
    WebService优点和缺点小结
    MongoDB监控之一:运行状态、性能监控,分析
    MongoDB分析工具之三:db.currentOp()
    Linux NFS服务器的安装与配置
    第三方支付 转
    视频监控/存储系统设计要点
    ViewPager禁止滑动以及它与内层滑动控件水平方向上事件冲突的解决方法
    (五)unity4.6Ugui中文教程文档-------概要-UGUI Interaction Components
    ListView列表拖拽排序
    shell脚本编写汇集
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/6977730.html
Copyright © 2011-2022 走看看