bash-基礎--數組和字符切片

                        數組

什麼是數組?

    變量:存儲單個元素的內存空間;

    數組:存儲多個元素的連續的內存空間;

    數組名:整個數組只有一個名字;

    數組索引:編號從0開始;

    數組名[索引],  ${ARRAY_NAME[INDEX]}

注意:bash-4及之後的版本,支持自定義索引格式,而不僅僅是0,1,2,...數字格式;

     此類數組稱之爲“關聯數組”





聲明數組:

     declare  -a  NAME:聲明索引數組;

     declare  -A  NAME:聲明關聯數組;



數組中元素的賦值方式:

        (1) 一次只賦值一個元素; ARRAY_NAME[INDEX]=value

        (2) 一次賦值全部元素;ARRAY_NAME=("VAL1"  "VAL2"  "VAL3"  ...)

        (3) 只賦值特定元素;ARRAY_NAME=([0]="VAL1"  [3]="VAL4" ...)

            注意:bash支持稀疏格式的數組;

        (4) read  -a  ARRAY_NAME  引用數組中的元素:${ARRAY_NAME[INDEX]}

            注意:引用時,只給數組名,表示引用下標爲0的元素;




數組的長度(數組中元素的個數):

           ${#ARRAY_NAME[*]}

           ${#ARRAY_NAME[@]}


示例:生成10個隨機數,並找出其中的最大值和最小值;

           

             #!/bin/bash
             #
                declare -a  rand
                declare -i max=0
            for i in {0..9}; do
                  rand[$i]=$RANDOM
                  echo ${rand[$i]}
                 [ ${rand[$i]} -gt $max ] && max=${rand[$i]}
            done

              echo "MAX: $max"




練習:定義一個數組,數組中的元素是/var/log目錄下所有以.log結尾的文件;統計其下標爲偶數的文件中的行數之和;

        

#!/bin/bash
        #
            declare -a files
            files=(/var/log/*.log)
            declare -i lines=0
        for i in $(seq 0 $[${#files[*]}-1]); do
            if [ $[$i%2] -eq 0 ]; then
                let lines+=$(wc -l ${files[$i]} | cut -d' ' -f1)
            fi
                done
        echo "Lines: $lines."


引用數組中的所有元素:

      ${ARRAY_NAME[*]}

      ${ARRAY_NAME[@]}


數組元素切片: ${ARRAY_NAME[@]:offset:number}

           offset:要路過的元素個數;

           number:要取出的元素個數;省略number時,表示取偏移量之後的所有元素;


向非稀疏格式數組中追加元素:ARRAY_NAME[${#ARRAY_NAME[*]}]=

刪除數組中的某元素:unset  ARRAY[INDEX]


關聯數組:

       declare  -A  ARRAY_NAME  注:聲明一個數組變量

       ARRAY_NAME=([index_name1]="value1"  [index_name2]="value2" ...)




 

                          字串切片



bash的內置字符串處理工具:

     字符串切片:${var:offset:number}

    取字符串的子串;取字符趾的最右側的幾個字符:${var:  -length} 

                                                注意:冒號後必須有一個空白字符;


基於模式取子串:

1、${var#*word}:其中word是指定的分隔符;功能:自左而右,查找var變量所存儲的字符串中,第一次出現的word分隔符,刪除字符串開頭至此分隔符之間的所有字符;

2、${var##*word}:其中word是指定的分隔符;功能:自左而右,查找var變量所存儲的字符串中,最後一次出現的word分隔符,刪除字符串開頭至此分隔符之間的所有字符;


舉例:mypath="/etc/init.d/functions"

3、${mypath##*/}:   functions

4、${mypath#*/}:  etc/init.d/functions

5、${var%word*}:其中word是指定的分隔符;功能:自右而左,查找var變量所存儲的字符串中,第一次出現的word分隔符,刪除此分隔符至字符串尾部之間的所有字符;

6、${var%%word*}:其中word是指定的分隔符;功能:自右而左,查找var變量所存儲的字符串中,最後一次出現的word分隔符,刪除此分隔符至字符串尾部之間的所有字符;


舉例:mypath="/etc/init.d/functions"

7、${mypath%/*}:  /etc/init.d


舉例:url=http://www.magedu.com:80

8、${url##*:}

9、${url%%:*}




查找替換:

1、${var/PATTERN/SUBSTI}:查找var所表示的字符串中,第一次被PATTERN所匹配到的字符串,將其替換爲SUBSTI所表示的字符串;

2、${var//PATTERN/SUBSTI}:查找var所表示的字符串中,所有被PATTERN所匹配到的字符串,並將其全部替換爲SUBSTI所表示的字符串;

4、${var/#PATTERN/SUBSTI}:查找var所表示的字符串中,行首被PATTERN所匹配到的字符串,將其替換爲SUBSTI所表示的字符串;

5、${var/%PATTERN/SUBSTI}:查找var所表示的字符串中,行尾被PATTERN所匹配到的字符串,將其替換爲SUBSTI所表示的字符串;

    注意:PATTERN中使用glob風格和通配符;




查找刪除:

1、${var/PATTERN}:以PATTERN爲模式查找var字符串中第一次的匹配,並刪除之;

2、${var//PATERN}

3、${var/#PATTERN}

4、${var/%PATTERN}




字符大小寫轉換:

1、${var^^}:把var中的所有小寫字符轉換爲大寫;

2、${var,,}:把var中的所有大寫字符轉換爲小寫;

3、變量賦值:

4、${var:-VALUE}:如果var變量爲空,或未設置,那麼返回VALUE;否則,則返回var變量的值; 

5、${var:=VALUE}:如果var變量爲空,或未設置,那麼返回VALUE,並將VALUE賦值給var變量;否則,     則返回var變量的值; 

6、${var:+VALUE}:如果var變量不空,則返回VALUE;

7、${var:?ERROR_INFO}:如果var爲空,或未設置,那麼返回ERROR_INFO爲錯誤提示;否則,返回var值; 








寫一個腳本:

ping命令去查看172.16.1.1-172.16.67.1範圍內的所有主機是否在線;在線的顯示爲up, 不在線的顯示down,分別統計在線主機,及不在線主機數;

分別使用for, while和until循環實現。

 for循環實現方式 

#!/bin/bash
                   #
                    declare -i uphosts=0
                    declare -i downhosts=0
                    for i in {1..17}; do
                        if ping -W 1 -c 1 172.16.$i.1 &> /dev/null; then
                            echo "172.16.$i.1 is up."
                            let uphosts+=1
                        else
                            echo "172.16.$i.1 is down."
                            let downhosts+=1
                        fi
                    done
                    echo "Up hosts: $uphosts, Down hosts: $downhosts."




while循環實現方式:

               

 #!/bin/bash
                    #
                            declare -i uphosts=0
                            declare -i downhosts=0
                            declare -i i=1
                        hostping() {
                            if ping -W 1 -c 1 $1 &> /dev/null; then
                                echo "$1 is up."
                                return 0
                            else
                                    echo "$1 is down."
                                    return 1
                            fi
                                }
                        while [ $i -le 67 ]; do
                            hostping 172.16.$i.1
                            [ $? -eq 0 ] && let uphosts++ || let downhosts++
                                let i++
                            done
                            echo "Up hosts: $uphosts, Down hosts: $downhosts."


寫一個腳本,實現:

能探測C類、B類或A類網絡中的所有主機是否在線;

                   

                           #!/bin/bash
                           #
                        cping() {
                                local i=1
                                while [ $i -le 5 ]; do
                                    if ping -W 1 -c 1 $1.$i &> /dev/null; then
                                            echo "$1.$i is up"
                                    else
                                            echo "$1.$i is down."
                                    fi
                                            let i++
                                            done
                                        }
                                bping() {
                                            local j=0
                                        while [ $j -le 5 ]; do
                                            cping $1.$j
                                            let j++
                                            done
                                          }
                                aping() {
                                            local x=0
                                        while [ $x -le 255 ]; do
                                            bping $1.$x
                                            let x++
                                            done
                                            }




信號捕捉trap




trap  'COMMAND'  SIGNALS  注:捕捉到 SIGNALS ,就執行'COMMAND'

   常可以進行捕捉的信號:HUP, INT(ctrl +c ) 

  


提示用戶輸入一個IP地址或網絡地址;獲取其網絡,並掃描其網段;           

 信號捕捉示例:
                        #!/bin/bash
                        #
                        declare -a hosttmpfiles
                        trap  'mytrap'  INT
        
                        mytrap()  {
                                    echo "Quit"
                                    rm -f ${hosttmpfiles[@]}
                                    exit 1
                                    }
        
                        for i in {1..50}; do
                                tmpfile=$(mktemp /tmp/ping.XXXXXX)
                            if ping -W 1 -c 1 172.16.$i.1 &> /dev/null; then
                                echo "172.16.$i.1 is up" | tee $tmpfile
                            else
                                 echo "172.16.$i.1 is down" | tee $tmpfile
                            fi
                                hosttmpfiles[${#hosttmpfiles[*]}]=$tmpfile
                         done
                            rm -f ${hosttmpfiles[@]}









&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

編外補充:

練習:寫一個腳本,完成如下功能

(1) 提示用戶輸入一個可執行命令的名稱;

(2) 獲取此命令所依賴到的所有庫文件列表;

(3) 複製命令至某目標目錄(例如/mnt/sysroot,即把此目錄當作根)下的對應的路徑中

bash,  /bin/bash  ==> /mnt/sysroot/bin/bash

useradd, /usr/sbin/useradd  ==>  /mnt/sysroot/usr/sbin/useradd

(4) 複製此命令依賴到的所有庫文件至目標目錄下的對應路徑下;

/lib64/ld-linux-x8664.so.2  ==>  /mnt/sysroot/lib64/ld-linux-x8664.so.2

進一步:

每次複製完成一個命令後,不要退出,而是提示用戶繼續輸入要複製的其它命令,並重復完成如上所描述的功能;直到用戶輸入“quit”退出腳本;








在bash中使用ACSII顏色

\033[31m hello \033[0m

##m:     

左側#:

3:前景色

4:背景色

右側#:顏色種類

1, 2, 3, 4, 5, 6, 7

#m:

加粗、閃爍等功能;

多種控制符,可組合使用,彼此間用分號隔開;

dialog命令可實現窗口化編程;

各窗體控件使用方式;

如何獲取用戶選擇或鍵入的內容?

默認,其輸出信息被定向到了錯誤輸出流;

《高級bash編程指南》,《Linux命令行和shell腳本編程寶典》


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章