Linux教程——Shell中字串與陣列操作例項

weixin_34054866發表於2017-01-01

Shell中字串與陣列操作例項

前言

本篇主要介紹了介紹在Shell指令碼中對於字串的處理,資料變數的定義與使用。

字串擷取及切割

子串擷取的三種用法:

  • ${var:起始位置:長度}
  • expr substr "$var" 起始位置 長度
  • echo $var | cut -b 起始位置-結束位置

字串的擷取,只是單純將字串擷取出來,對原來的變數並不會進行修改。

${var:起始位置:長度}

SCHOOL="This is string."
echo ${#SCHOOL}    //確定變數的長度
echo ${SCHOOL:0:6}

使用${}方式擷取字串時,起始位置是從0開始的(和陣列下標編號類似)。

expr substr "$var" 起始位置 長度

expr substr "$var" 起始位置 長度

expr substr "$SCHOOL" 1 6

使用expr substr擷取字串時,起始編號從1開始,這個要注意與${}相區分。

注意:因為SCHOOL變數的值裡含有空格,所以應該加雙引號進行呼叫,否則是會報錯的

echo $var | cut -b 起始位置-結束位置

選項 -b 表示按位元組擷取字元,其中起始位置、結束位置都可以省略。當省略起始位置時,視為從第1個字元開始(編號也是從1開始,與expr類似),當省略結束位置時,視為擷取到最後。

echo $SCHOOL | cut -b 1-6

路徑分割:

  • 取目錄位置:dirname "字串"
  • 取文件的基本名稱:basename "字串"

字串的替換

子串替換的兩種用法:

只替換第一個匹配結果:${var/old/new}

echo  ${SCHOOL/r/RRRR}    

替換全部匹配結果:${var//old/new}

echo  ${SCHOOL//r/RRRR}

字串掐頭去尾:

從左向右,最短匹配刪除:${變數名#*關鍵詞}

echo ${MAIL#*oo}
echo ${MAIL#*/}

從左向右,最長匹配刪除:${變數名##*關鍵詞}

echo ${MAIL##*oo}
echo ${MAIL##*/}

從右向左,最短匹配刪除:${變數名%關鍵詞*}

echo ${MAIL%oo*}
echo ${MAIL%/*}

從右向左,最長匹配刪除:${變數名%%關鍵詞*}

echo ${MAIL%%oo*}
echo ${MAIL%%/*}

要適應不同副檔名檔案的修改,並能夠反向還原。
修改前的副檔名、修改後的副檔名通過位置變數 $1、$2提供。

vim ../renfilex.sh
#!/bin/bash
for FILE in "$1"
do
    mv $FILE ${FILE%$1}"$2"
done

字串初值的處理

只取值,${var:-word}
若變數var已存在且非Null,則返回 $var 的值;否則返回字串“word”,原變數var的值不受影響。

取值+賦值,${var:=word}
若變數var已存在且非Null,則返回 $var 的值,原變數值不變;否則返回字串“word”,並將此字串賦值給變數 var。

資料的定義和使用

建立陣列的方法:

  • 格式1,整體賦值:陣列名=(值1 值2 .. .. 值n)
  • 格式2,單個元素賦值:陣列名[下標]=值

檢視陣列元素的方法:

  • 獲取單個陣列元素:${陣列名[下標]}
  • 獲取所有陣列元素:${陣列名[@]}
  • 獲取陣列元素個數:${#陣列名[@]}
  • 獲取連續的多個陣列元素:${陣列名[@]:起始下標:元素個數}
  • 獲取某個陣列元素的長度:${#陣列名[下標]}
  • 擷取陣列元素值的一部分:${#陣列名[下標]:起始下標:字元數}

declare命令的使用

在Shell環境中,變數預設均作為字串處理,當參與expr、$[]數學運算時自動作為整數處理。比如,使用“1+2”、“X+2”、“$X+2”表示式是無法將運算結果直接作為整數賦值給指定的變數的:

[root@service99 ~]# X=24
[root@service99 ~]# A=1+2
[root@service99 ~]# echo $A
1+2                                  //賦值結果為字串
[root@service99 ~]# A=X+2
[root@service99 ~]# echo $A
X+2                                  //賦值結果為字串
[root@service99 ~]# A=$X+2
[root@service99 ~]# echo $A
24+2               

若要將一個變數強制設定為整數,可以使用declare命令宣告(-i選項):

    [root@service99 ~]# declare -i A          //先將A宣告為整數變數
    [root@service99 ~]# A=1+2                  //然後賦值
    [root@service99 ~]# echo $A                  //確認結果
    3
    [root@service99 ~]# declare -i B=$X+2      //也可以在宣告的同時進行賦值
    [root@service99 ~]# echo $B
    26

declare命令結合-x選項,可以將區域性變數設定為全域性變數,這個與export命令的作用差不多:

    [root@service99 ~]# declare -x NM="Tarena"      //新建全域性變數NM

如果要取消變數的全域性屬性,可以使用“+x”選項:

    [root@service99 ~]# declare +x NM              //將NM恢復為區域性變數  

declare命令結合-r選項,可以為變數設定“只讀”屬性,只讀變數的值不允許再被修改,通常可用來儲存一些固定的引數,避免無意中被修改:

    [root@service99 ~]# echo $NM
    Tarena
    [root@service99 ~]# declare -r NM                  //將變數NM設定為只讀
    [root@service99 ~]# NM="Tarena IT Group."          //重新賦值失敗
-bash: NM: readonly variable

只讀變數除了不能修改值以外,也無法被unset清除(若要清除只讀變數,需要退出當前Shell程式):

    [root@service99 ~]# unset NM
-bash: unset: NM: cannot unset: readonly variable

使用declare命令,結合-a選項可宣告一個陣列(這個操作一般可不做),比如:

    [root@service99 ~]# declare -a SVRS

直接執行declare -a,即不指定陣列名引數時,會列出當前Shell環境中已定義的所有陣列設定:

    [root@service99 ~]# declare -a                  //檢視已定義的陣列

若要定義陣列的成員,可以在declare宣告時定義,也可以直接整體定義。整體賦值的格式為“陣列名=(值1 值2 值3 .. ..)”,比如:

    [root@service99 ~]# MY_SVRS=(www ftp mail club)
    [root@service99 ~]# set | grep "MY_"              //檢視陣列定義結果

Shell中的語法要求是比較鬆散的,所以我們也可以直接為單個陣列元素賦值,格式為“陣列名[下標]=值”,每個陣列元素的編號(即下標)從0開始。比如,以下操作會產生一個包括3個元素的陣列:

    [root@service99 ~]# WEB_SVRS[0]="www.tarena.com"          //為第1個元素賦值
    [root@service99 ~]# WEB_SVRS[1]="mail.tarena.com"          //為第2個元素賦值
    [root@service99 ~]# WEB_SVRS[2]="club.tarena.com"          //為第3個元素賦值

為陣列元素賦值時,並不要求每個成員都需要指定,下標也可以不連續。比如,可跳過下標3,直接為下標為4的元素賦值:
3)檢視陣列、檢視陣列元素

輸出整個陣列的內容:

    [root@service99 ~]# echo ${MY_SVRS[@]}

檢視第1個(下標為0的)陣列元素:

[root@service99 ~]# echo ${MY_SVRS[0]}

輸出陣列中下標從1開始的2個元素:

    [root@service99 ~]# echo ${MY_SVRS[@]:1:2}

檢視陣列的元素個數:

    [root@service99 ~]# echo ${#MY_SVRS[@]}

當陣列元素的內容較多時,直接輸出 ${陣列名[@]} 可能不方便檢視,這種情況下可以利用迴圈遍歷陣列元素,通過連續取值的操作(或者 % 取模運算)限定每行只顯示多少個IP地址(比如4個) 。

相關文章