bash的變量與數組html
變量:存儲單個元素的內存空間; 也至關因而數組的0號索引。
數組:存儲多個元素的連續的內存空間;shell
1、變量數組
一、介紹:bash
任何程序都須要變量。 變量是用來存儲數據的。程序=指令+數據。
按照其變量是否須要嚴格定義其類型來劃分 :ide
強類型語言: 簡單講就是嚴格區分變量類型,使用以前必需要聲明一個變量的類型。如C、Python。函數
弱類型語言: 不強制區分變量的類型,在使用以前不用明確聲明一個變量的類型,有默認的類型,通常默認是字符型的,用到時直接使用,直接賦值。 如:bash。ui
定義變量類型的做用:google
數據存儲格式;url
數據的有效存儲範圍,有效取值範圍都不同,如 C語言的 整型,長整型。spa
比較機制不一樣,運算類型也不一樣。如字符 2加上3,等於 23. 而數值就是5.
不一樣類型的數據不能運算, 只能轉換之後再運算。
變量的命令要求: 變量名其實就是指向的內存空間地址
只能使用數字、字母和下劃線組成;
不能以數字開頭;
不能使用程序中的關鍵字;
要見名知義。命名機制遵循某種法則;不可以使用程序的保留字,例如if, else, then, while等等;
二、定義變量:
本地變量:只對當前shell進程有效,對其子shell及其它shell都無效。
定義變量:[set]Var_name="Value"
引用變量:${Var_Name}
撤銷變量:unset Var_Name
局部變量:僅對局部代碼生效,只能在函數中使用。引用和撤銷與上面相同
定義變量:local Var_Name="Value"
環境變量: 對當前shell及其子shell有效,因此在當前shell中所執行的腳本也可使用這種變量,腳本的運行環境就是子shell。
定義變量:
(1) export name=value
(2) name=value ; export name 反過來也同樣。
(3) declare -x name=value
(4) name=value ; declare -x name
位置變量:用以引用執行腳本或函數時的所調用的變量。
$1,$2......$n, 對應的就是第一、二、n個參數。數字兩位的時候,要用{}括起來。
#!/bin/bash # echo "$1 $2 $3" star@sst-pp:/tmp$ bash test.sh user group shell user group shell
特殊變量:
$0: 腳本名稱自身。
$?: 上一條命令的執行狀態。狀態返回值。狀態用數字來表示: 0-255;0 成功;1-255: 失敗。失敗狀態中: 1,2(命令參數錯誤),127(沒有命令),255 是預留的。 咱們能夠手動定義其它的。
$$ 當前shell的PID
$! Shell最後運行的後臺進程的PID
$# 參數數量
$* 全部參數
$@ 全部參數
$- 使用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.....
查看環境變量:export, declare -x, printenv, env
撤銷環境變量:unset name
只讀變量:
定義變量:
declare -r name
readonly name
只讀變量沒法從新賦值,而且不支持撤銷;存活時間爲當前shell進程的生命週期,隨shell進程終止而終止;
三、字符串變量修改:
只是輸出,不是修改變量的值。一般用於賦值的時候。
變量是由bash提供的,因此一些操做也都支持glob風格的通配符。
下面在普通變量上面用到的功能,在數組上大部分也均可以使用。
之前寫的,不怎麼樣,可是稍微詳細點:
http://fanqie.blog.51cto.com/9382669/1649669
下面的例子中用到的變量:
hi變量保存有"Hello World"
see變量保存有"/etc/systemd/system.conf"
字符串切片:
${var:offset:number}: 取字符串的子串, 變量:偏移數:取字符數。與數組索引同樣,0表示第一個元素,只不過在變量裏第一個元素就是表示第一個字符。
echo ${hi:3:2} 值:lo 從第四個字符開始,取2個。
切片也支持負數,取字符串的最右側的幾個字符:${var: -length}
注意:以負數取值,冒號後必須有一個空白字符;如:${arr: -8} 顯示後面的8個字符。
echo ${hi: -2} 值:ld
也能夠定義結束範圍:echo ${arr:3:-9},3到-9之間的字符。3和-9只是用來標識位置的,而不是用來定義有哪些內容的,負數就是從右到左。而最終數據取值只能是從左到右。
echo ${hi:3:-2} 值:lo Wor
基於模式取子串:
${var#*word}:其中word是指定的分隔符;
功能:最短自左而右匹配,刪除全部匹配到的字符。*是通配符。
echo ${hi#?e} 值:llo World
echo ${hi#*o} 值:World
echo ${hi#*o W} 值:orld
echo ${see#*/} 值:etc/systemd/system.conf
${var##*word}:其中word是指定的分隔符;
功能:最長自左而右匹配,刪除全部匹配到的字符。*是通配符。
echo ${see##*/} 值:system.conf
${var%word*}:其中word是指定的分隔符;
功能:最短自右而左匹配,刪除全部匹配到的字符。
echo ${see%/*} 值:/etc/systemd
這個完成了取路徑的目錄名,而上面的##完成了取路徑基名。
${var%%word*}:其中word是指定的分隔符;
功能:最長自右而左匹配,刪除全部匹配到的字符。
echo ${see%%/*} 值:
echo ${hi%%l*} 值:He
echo ${url%%:*} 值:https
#號標識數據的首部。 %用來標識尾部。
hi變量保存有"Hello World"
查找替換:PATTERN中可使用glob通配符;
${var/PATTERN/SUBSTI}:查找var所表示的字符串中,第一次被PATTERN所匹配到的字符串,並將其替換爲SUBSTI所表示的字符串;
echo ${hi/l/L} 值:HeLlo World
echo ${hi/ll/LL} 值:HeLLo World
echo ${hi/*o/L} 值:Lrld
${var//PATTERN/SUBSTI}:查找var所表示的字符串中,全部被PATTERN所匹配到的字符串,並將其所有替換爲SUBSTI所表示的字符串;
echo ${hi//l/L} 值:HeLLo WorLd
${var/#PATTERN/SUBSTI}:查找var所表示的字符串中,行首被PATTERN所匹配到的字符串,將其替換爲SUBSTI所表示的字符串;比/多了限制,只能從左每個字符開始匹配成功。
echo ${hi/#l/L} 值:Hello World
echo ${hi/#H/L} 值:Lello World
echo ${hi/#*o/L} 值:Lrld
${var/%PATTERN/SUBSTI}:查找var所表示的字符串中,行尾被PATTERN所匹配到的字符串,將其替換爲SUBSTI所表示的字符串;與上面意思同樣,只不過是從右到左。
查找刪除:(see爲/etc/systemd/system.conf)
${var/PATTERN}:刪除以PATTERN爲模式第一次匹配到的var字符串。這裏不用替換了,下接刪除。
與#不一樣的是,這個是定點刪除,而#是範圍刪除。固然若是加上通配符也同樣。
echo ${see/\/systemd} 值:/etc/system.conf
${var//PATERN} 刪除以PATTERN爲模式全部匹配到的var字符串。
${var/#PATTERN} 以左邊界匹配。
${var/%PATTERN} 以右邊界匹配。
字符大小寫轉換:
${var^^}:把var中的全部小寫字符轉換爲大寫;
${var,,}:把var中的全部大寫字符轉換爲小寫;
這個也能夠用一個^或,來表示。 只轉換一個字母。也能夠用#或%來定義邊界。
變量賦值:
${var:-VALUE}:若是var變量爲空,或未設置,那麼返回VALUE;不然,則返回var變量的值;
${var:=VALUE}:若是var變量爲空,或未設置,那麼返回VALUE,並將VALUE賦值給var變量;不然,則返回var變量的值;
${var:+VALUE}:若是var變量不空,則返回VALUE;
${var:?ERROR_INFO}:若是var爲空,或未設置,那麼返回ERROR_INFO爲錯誤提示;不然,返回var值;
而VALUE不僅僅只能用字符,也能夠用變量引用來表示數據。
變量中字符的個數:
${#var}
2、數組:
在普通變量上面用到的功能,在數組上大部分也均可以使用。
數組名:整個數組只有一個名字;
數組索引:編號從0開始;0是第一個索引。
bash-4及以後的版本開始支持"關聯數組",也就是索引不是以數字表示,而是以自定義的字符串來表示。
聲明數組:
declare -a NAME:聲明索引數組; 這個不用顯示的聲明,賦值的同時就自動生成數組了。
declare -A NAME:聲明關聯數組; 這個須要先在賦值以前聲明。
賦值方式:
一次只賦值一個元素;
ARRAY_NAME[INDEX]=value
只給0和5賦值了,其它索引都沒有值。
一次賦值所有元素;會把上面單獨定義的覆蓋
能夠看到,賦值索引是0,1,2 可是原來的5的值也沒有了。
只賦值特定元素;這個也會覆蓋數據。
ARRAY_NAME=([0]="VAL1" [3]="VAL4" ...)
bash支持稀疏格式的數組;就是不按順序來的索引。
read -a ARRAY_NAME
能夠用read來獲取輸入爲數組賦值。
也就只有第一種不會覆蓋不一樣索引的數據。如:
數組的長度(數組中元素的個數):
${#ARRAY_NAME[*]}
echo ${#abc[*]} 5
與變量同樣,只不過這裏元素個數,那裏是字符個數。固然也能夠查看某元素的字符的個數。
echo ${#abc[1]} 3
${#ARRAY_NAME[@]}
這個與*是同樣的。
引用數組中的元素:
${ARRAY_NAME[INDEX]}
注意:引用時若是隻給數組名,表示引用下標爲0的元素;
引用數組中的全部元素:
${ARRAY_NAME[*]}
${ARRAY_NAME[@]}
數組元素切片:
${ARRAY_NAME[@]:offset:number}
offset:偏移的元素個數;
number:要取出的元素個數;省略number時,表示取偏移量以後的全部元素;
${arry[*]:3:2}
加上*來輸出全部數據,再由3和2來定位哪一個位置
若是不加*,數據只是一個字符塊,會當作變量來操做。
變量也能夠這樣偏移,並且個數部分還能夠用負數。咱們上面變量部分已經試過了。
字符大小寫轉換
追加元素:
由於索引是從0開始,正好與個數少1。因此只要計算出元素個數,給個數賦值便可。
只能是非稀疏格式的數組,由於稀疏格式是沒有順序的,可能有的索引位是8,但元素的個數卻只有2個,這樣追加追加,一下子就把8給覆蓋了。
ARRAY_NAME[${#ARRAY_NAME[*]}]=
紅色部分是用來取出數組元素的個數。
刪除數組中的某元素:
關聯數組:
declare -A ARRAY_NAME
ARRAY_NAME=([index_name1]="value1" [index_name2]="value2" ...)
index_name就是自定義的字符串,它來作爲索引,或許稱爲鍵。賦值方式與索引數組也沒有什麼不一樣。