bash腳本之一(變量+數組)

bash的變量與數組html

變量:存儲單個元素的內存空間; 也至關因而數組的0號索引。
數組:存儲多個元素的連續的內存空間;
shell

1、變量數組

一、介紹:bash

任何程序都須要變量。 變量是用來存儲數據的。程序=指令+數據。
按照其變量是否須要嚴格定義其類型來劃分 :ide

  1. 強類型語言: 簡單講就是嚴格區分變量類型,使用以前必需要聲明一個變量的類型。如C、Python。函數

  2. 弱類型語言: 不強制區分變量的類型,在使用以前不用明確聲明一個變量的類型,有默認的類型,通常默認是字符型的,用到時直接使用,直接賦值。 如:bash。ui


定義變量類型的做用:google

  1. 數據存儲格式;url

  2. 數據的有效存儲範圍,有效取值範圍都不同,如 C語言的 整型,長整型。spa

  3. 比較機制不一樣,運算類型也不一樣。如字符 2加上3,等於 23.  而數值就是5.

  4. 不一樣類型的數據不能運算, 只能轉換之後再運算。


變量的命令要求: 變量名其實就是指向的內存空間地址

  1. 只能使用數字、字母和下劃線組成;

  2. 不能以數字開頭;

  3. 不能使用程序中的關鍵字;

  4. 要見名知義。命名機制遵循某種法則;不可以使用程序的保留字,例如if, else, then, while等等;


二、定義變量:

本地變量:只對當前shell進程有效,對其子shell及其它shell都無效。

  1. 定義變量:[set]Var_name="Value" 

  2. 引用變量:${Var_Name}

  3. 撤銷變量:unset Var_Name


局部變量:僅對局部代碼生效,只能在函數中使用。引用和撤銷與上面相同

  1. 定義變量:local Var_Name="Value"


環境變量: 對當前shell及其子shell有效,因此在當前shell中所執行的腳本也可使用這種變量,腳本的運行環境就是子shell。

  1. 定義變量:
    (1) export name=value
    (2) name=value ; export name    反過來也同樣。
    (3) declare -x name=value
    (4) name=value ; declare -x name


位置變量:用以引用執行腳本或函數時的所調用的變量。

  1. $1,$2......$n,   對應的就是第一、二、n個參數。數字兩位的時候,要用{}括起來。

#!/bin/bash
#
echo "$1 $2 $3"

star@sst-pp:/tmp$ bash test.sh user group shell
user group shell


特殊變量:

  1. $0: 腳本名稱自身。

  2. $?: 上一條命令的執行狀態。狀態返回值。狀態用數字來表示: 0-255;0 成功;1-255: 失敗。失敗狀態中: 1,2(命令參數錯誤),127(沒有命令),255  是預留的。 咱們能夠手動定義其它的。

  3. $$   當前shell的PID

  4. $!    Shell最後運行的後臺進程的PID

  5. $#   參數數量

  6. $*   全部參數

  7. $@   全部參數

  8. $-    使用Set命令設定的Flag一覽

下面摘自:http://blog.chinaunix.net/uid-26527046-id-3336483.html

$* :
      位置參數從參數 1 開始。若是在雙引號中進行擴展,則擴展就是一個詞,由 IFS 特殊變量的第一個字符
將參數分開,若是 IFS 爲空,則沒有間隔空格。IFS 的默認值是空白、製表符和換行符。若是沒有設置 IFS,
則使用空白做爲分隔符(僅對默認 IFS 而言)。
$@ :
      位置參數從參數 1 開始。若是在雙引號中進行擴展,則每一個參數都會成爲一個詞,所以 「$@」 與 
「$1」 「$2」 等效。若是參數有可能包含嵌入空白,那麼您將須要使用這種形式。



bash內嵌的環境變量(一般爲全大寫字符):用於定義bash的工做環境
如:PATH, HISTFILE, HISTSIZE, HISTFILESIZE, HISTCONTROL, SHELL, HOME, UID, PWD, OLDPWD.....

  1. 查看環境變量:export, declare -x, printenv, env

  2. 撤銷環境變量:unset name


只讀變量:

  1. 定義變量:

    declare -r name
    readonly name
    只讀變量沒法從新賦值,而且不支持撤銷;存活時間爲當前shell進程的生命週期,隨shell進程終止而終止;


三、字符串變量修改:

只是輸出,不是修改變量的值。一般用於賦值的時候。

變量是由bash提供的,因此一些操做也都支持glob風格的通配符。
下面在普通變量上面用到的功能,在數組上大部分也均可以使用。

之前寫的,不怎麼樣,可是稍微詳細點:

http://fanqie.blog.51cto.com/9382669/1649669

下面的例子中用到的變量:

hi變量保存有"Hello World"

see變量保存有"/etc/systemd/system.conf"

字符串切片:

  1. ${var:offset:number}: 取字符串的子串, 變量:偏移數:取字符數。與數組索引同樣,0表示第一個元素,只不過在變量裏第一個元素就是表示第一個字符。

    echo ${hi:3:2}            值:lo   從第四個字符開始,取2個。


  2. 切片也支持負數,取字符串的最右側的幾個字符:${var:  -length}
    注意:以負數取值,冒號後必須有一個空白字符;如:${arr: -8} 顯示後面的8個字符。

    echo ${hi: -2}            值:ld


  3. 也能夠定義結束範圍:echo ${arr:3:-9},3到-9之間的字符。3和-9只是用來標識位置的,而不是用來定義有哪些內容的,負數就是從右到左。而最終數據取值只能是從左到右。

    echo ${hi:3:-2}        值:lo Wor


基於模式取子串:

  1. ${var#*word}:其中word是指定的分隔符;
    功能:最短自左而右匹配,刪除全部匹配到的字符。*是通配符。

    echo ${hi#?e}        值:llo World

    echo ${hi#*o}        值:World

    echo ${hi#*o W}    值:orld

    echo ${see#*/}        值:etc/systemd/system.conf


  2. ${var##*word}:其中word是指定的分隔符;

    功能:最長自左而右匹配,刪除全部匹配到的字符。*是通配符。
    echo ${see##*/}        值:system.conf


  3. ${var%word*}:其中word是指定的分隔符;
    功能:最短自右而左匹配,刪除全部匹配到的字符。

    echo ${see%/*}        值:/etc/systemd

    這個完成了取路徑的目錄名,而上面的##完成了取路徑基名。


  4. ${var%%word*}:其中word是指定的分隔符;

    功能:最長自右而左匹配,刪除全部匹配到的字符。

    echo ${see%%/*}        值:

    echo ${hi%%l*}        值:He

    url=https://www.google.com.hk

    echo ${url%%:*}        值:https



#號標識數據的首部。 %用來標識尾部。

hi變量保存有"Hello World"

查找替換:PATTERN中可使用glob通配符;

  1. ${var/PATTERN/SUBSTI}:查找var所表示的字符串中,第一次被PATTERN所匹配到的字符串,並將其替換爲SUBSTI所表示的字符串;
    echo ${hi/l/L}        值:HeLlo World

    echo ${hi/ll/LL}        值:HeLLo World

    echo ${hi/*o/L}        值:Lrld


  2. ${var//PATTERN/SUBSTI}:查找var所表示的字符串中,全部被PATTERN所匹配到的字符串,並將其所有替換爲SUBSTI所表示的字符串;
    echo ${hi//l/L}        值:HeLLo WorLd


  3. ${var/#PATTERN/SUBSTI}:查找var所表示的字符串中,行首被PATTERN所匹配到的字符串,將其替換爲SUBSTI所表示的字符串;比/多了限制,只能從左每個字符開始匹配成功。

    echo ${hi/#l/L}        值:Hello World

    echo ${hi/#H/L}        值:Lello World

    echo ${hi/#*o/L}        值:Lrld


  4. ${var/%PATTERN/SUBSTI}:查找var所表示的字符串中,行尾被PATTERN所匹配到的字符串,將其替換爲SUBSTI所表示的字符串;與上面意思同樣,只不過是從右到左。


查找刪除:(see爲/etc/systemd/system.conf)

  1. ${var/PATTERN}:刪除以PATTERN爲模式第一次匹配到的var字符串。這裏不用替換了,下接刪除。

    與#不一樣的是,這個是定點刪除,而#是範圍刪除。固然若是加上通配符也同樣。

    echo ${see/\/systemd}        值:/etc/system.conf


  2. ${var//PATERN}  刪除以PATTERN爲模式全部匹配到的var字符串。


  3. ${var/#PATTERN}  以左邊界匹配。


  4. ${var/%PATTERN}  以右邊界匹配。



字符大小寫轉換:

  1. ${var^^}:把var中的全部小寫字符轉換爲大寫;

  2. ${var,,}:把var中的全部大寫字符轉換爲小寫;

    這個也能夠用一個^或,來表示。 只轉換一個字母。也能夠用#或%來定義邊界。


變量賦值:

  1. ${var:-VALUE}:若是var變量爲空,或未設置,那麼返回VALUE;不然,則返回var變量的值;

  2. ${var:=VALUE}:若是var變量爲空,或未設置,那麼返回VALUE,並將VALUE賦值給var變量;不然,則返回var變量的值;

  3. ${var:+VALUE}:若是var變量不空,則返回VALUE;

  4. ${var:?ERROR_INFO}:若是var爲空,或未設置,那麼返回ERROR_INFO爲錯誤提示;不然,返回var值;

    而VALUE不僅僅只能用字符,也能夠用變量引用來表示數據。


變量中字符的個數:

  1. ${#var}


2、數組:

在普通變量上面用到的功能,在數組上大部分也均可以使用。


數組名:整個數組只有一個名字;
數組索引:編號從0開始;0是第一個索引。
bash-4及以後的版本開始支持"關聯數組",也就是索引不是以數字表示,而是以自定義的字符串來表示。

聲明數組:
       declare  -a  NAME:聲明索引數組;  這個不用顯示的聲明,賦值的同時就自動生成數組了。
       declare  -A  NAME:聲明關聯數組;  這個須要先在賦值以前聲明。
       
賦值方式:

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

    wKioL1a9nUmQkpgWAABLrI2YCRo805.png

    只給0和5賦值了,其它索引都沒有值。


  2. 一次賦值所有元素;會把上面單獨定義的覆蓋

    wKioL1a9ndmQQR9iAABdZqVcKVI330.png

    能夠看到,賦值索引是0,1,2 可是原來的5的值也沒有了。


  3. 只賦值特定元素;這個也會覆蓋數據。
    ARRAY_NAME=([0]="VAL1"  [3]="VAL4" ...)
    bash支持稀疏格式的數組;就是不按順序來的索引。

    wKiom1a9nxijv7JoAABffLvhVj8465.png

  4. read  -a  ARRAY_NAME
    能夠用read來獲取輸入爲數組賦值。
    wKioL1a9m_bjJovaAAASeH__uBI956.png


也就只有第一種不會覆蓋不一樣索引的數據。如:

  1. wKiom1a9n92wcisgAABVG5-i76U548.png




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

  1. ${#ARRAY_NAME[*]}

    echo ${#abc[*]}            5

    與變量同樣,只不過這裏元素個數,那裏是字符個數。固然也能夠查看某元素的字符的個數。

    echo ${#abc[1]}            3


  2. ${#ARRAY_NAME[@]}

    這個與*是同樣的。

   
引用數組中的元素

  1. ${ARRAY_NAME[INDEX]}
    注意:引用時若是隻給數組名,表示引用下標爲0的元素;

  2. 引用數組中的全部元素:
    ${ARRAY_NAME[*]}
    ${ARRAY_NAME[@]}


數組元素切片:

  1. ${ARRAY_NAME[@]:offset:number}
    offset:偏移的元素個數;
    number:要取出的元素個數;省略number時,表示取偏移量以後的全部元素;
    ${arry[*]:3:2}
    加上*來輸出全部數據,再由3和2來定位哪一個位置
    若是不加*,數據只是一個字符塊,會當作變量來操做。

    變量也能夠這樣偏移,並且個數部分還能夠用負數。咱們上面變量部分已經試過了。


字符大小寫轉換

  1. ${ARRAY_NAME[*]^^}:把數組中的全部元素轉換爲大寫;

    wKiom1a9pOLR76uxAAAWhaeXaxk441.png

  2. ${ARRAY_NAME[0]^^}:把數組中的0索引元素轉換爲大寫;
    wKioL1a9pXLAnROpAAAO1EIFR28506.png

  3. 也能夠用一個^或,來表示只給首字母變化。
    wKiom1a9pU2yBlibAAAScW7VpU4273.png


追加元素:

  1. 由於索引是從0開始,正好與個數少1。因此只要計算出元素個數,給個數賦值便可。

  2. 只能是非稀疏格式的數組,由於稀疏格式是沒有順序的,可能有的索引位是8,但元素的個數卻只有2個,這樣追加追加,一下子就把8給覆蓋了。
    ARRAY_NAME[${#ARRAY_NAME[*]}]=
    紅色部分是用來取出數組元素的個數。

  3. wKioL1a9qAixLiinAAA1ksrn6-c301.png


刪除數組中的某元素:

  1. unset  ARRAY[INDEX]

    wKiom1a9qDeTx_s5AAAcJ8gmxeI153.png

  2. unset ARRAY            刪除數組

    wKioL1a9qKbhvrgWAAAcJ8gmxeI446.png


關聯數組:

  1. declare  -A  ARRAY_NAME
    ARRAY_NAME=([index_name1]="value1"  [index_name2]="value2" ...)
    index_name就是自定義的字符串,它來作爲索引,或許稱爲鍵。賦值方式與索引數組也沒有什麼不一樣。

    wKiom1a9qb_gn64GAAAygtU-xu0892.png

    wKiom1a9qnzSPGdxAABm8aueZWU203.png



謝謝瀏覽。j_0022.gif

相關文章
相關標籤/搜索