2012年12月7日 星期五

bash shell 環境變數內容的刪除與取代

[root@www ~]# echo $path
/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:
/sbin:/bin:/usr/sbin:/usr/bin:/root/bin  <==這兩行其實是同一行啦!

範例二:假設我不喜歡 kerberos,所以要將前兩個目錄刪除掉,如何顯示?
[root@www ~]# echo ${path#/*kerberos/bin:}
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

上面這個範例很有趣的!他的重點可以用底下這張表格來說明:

${variable#/*kerberos/bin:}
   上面的特殊字體部分是關鍵字!用在這種刪除模式所必須存在的

${variable#/*kerberos/bin:}
   這就是原本的變數名稱,以上面範例二來說,這裡就填寫 path 這個『變數名稱』啦!

${variable#/*kerberos/bin:}
   這是重點!代表『從變數內容的最前面開始向右刪除』,且僅刪除最短的那個

${variable#/*kerberos/bin:}
   代表要被刪除的部分,由於 # 代表由前面開始刪除,所以這裡便由開始的 / 寫起。
   需要注意的是,我們還可以透過萬用字元 * 來取代 0 到無窮多個任意字元

   以上面範例二的結果來看, path 這個變數被刪除的內容如下所示:
/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:
/sbin:/bin:/usr/sbin:/usr/bin:/root/bin  <==這兩行其實是同一行啦!

# :符合取代文字的『最短的』那一個;
##:符合取代文字的『最長的』那一個;



上面談到的是『從前面開始刪除變數內容』,那麼如果想要『從後面向前刪除變數內容』呢? 這個時候就得使用百分比 (%) 符號了!來看看範例四怎麼做吧!

範例四:我想要刪除最後面那個目錄,亦即從 : 到 bin 為止的字串
[root@www ~]# echo ${path%:*bin}
/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:
/sbin:/bin:/usr/sbin:/usr/bin  <==注意啊!最後面一個目錄不見去!
# 這個 % 符號代表由最後面開始向前刪除!所以上面得到的結果其實是來自如下:
# /usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:
# /usr/sbin:/usr/bin:/root/bin  <==這兩行其實是同一行啦!

範例五:那如果我只想要保留第一個目錄呢?
[root@www ~]# echo ${path%%:*bin}
/usr/kerberos/sbin
# 同樣的, %% 代表的則是最長的符合字串,所以結果其實是來自如下:
# /usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:
# /usr/sbin:/usr/bin:/root/bin  <==這兩行其實是同一行啦!


瞭解了刪除功能後,接下來談談取代吧!繼續玩玩範例六囉!

範例六:將 path 的變數內容內的 sbin 取代成大寫 SBIN:
[root@www ~]# echo ${path/sbin/SBIN}
/usr/kerberos/SBIN:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:
/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
# 這個部分就容易理解的多了!關鍵字在於那兩個斜線,兩斜線中間的是舊字串
# 後面的是新字串,所以結果就會出現如上述的特殊字體部分囉!

[root@www ~]# echo ${path//sbin/SBIN}
/usr/kerberos/SBIN:/usr/kerberos/bin:/usr/local/SBIN:/usr/local/bin:
/SBIN:/bin:/usr/SBIN:/usr/bin:/root/bin
# 如果是兩條斜線,那麼就變成所有符合的內容都會被取代喔!
我們將這部份作個總結說明一下:

變數設定方式說明
${變數#關鍵字}
${變數##關鍵字}
若變數內容從頭開始的資料符合『關鍵字』,則將符合的最短資料刪除
若變數內容從頭開始的資料符合『關鍵字』,則將符合的最長資料刪除
${變數%關鍵字}
${變數%%關鍵字}
若變數內容從尾向前的資料符合『關鍵字』,則將符合的最短資料刪除
若變數內容從尾向前的資料符合『關鍵字』,則將符合的最長資料刪除
${變數/舊字串/新字串}
${變數//舊字串/新字串}
若變數內容符合『舊字串』則『第一個舊字串會被新字串取代』
若變數內容符合『舊字串』則『全部的舊字串會被新字串取代』

變數的測試與內容替換 


在某些時刻我們常常需要『判斷』某個變數是否存在,若變數存在則使用既有的設定,若變數不存在則給予一個常用的設定。 我們舉底下的例子來說明好了,看看能不能較容易被你所理解呢!

範例一:測試一下是否存在 username 這個變數,若不存在則給予 username 內容為 root
[root@www ~]# echo $username
           <==由於出現空白,所以 username 可能不存在,也可能是空字串
[root@www ~]# username=${username-root}
[root@www ~]# echo $username
root       <==因為 username 沒有設定,所以主動給予名為 root 的內容。
[root@www ~]# username="vbird tsai" <==主動設定 username 的內容
[root@www ~]# username=${username-root}
[root@www ~]# echo $username
vbird tsai <==因為 username 已經設定了,所以使用舊有的設定而不以 root 取代
在上面的範例中,重點在於減號『 - 』後面接的關鍵字!基本上你可以這樣理解:

new_var=${old_var-content}
   新的變數,主要用來取代舊變數。新舊變數名稱其實常常是一樣的

new_var=${old_var-content}
   這是本範例中的關鍵字部分!必須要存在的哩!

new_var=${old_var-content}
   舊的變數,被測試的項目!

new_var=${old_var-content}
   變數的『內容』,在本範例中,這個部分是在『給予未設定變數的內容』
不過這還是有點問題!因為 username 可能已經被設定為『空字串』了!果真如此的話,那你還可以使用底下的範例來給予 username 的內容成為 root 喔!

範例二:若 username 未設定或為空字串,則將 username 內容設定為 root
[root@www ~]# username=""
[root@www ~]# username=${username-root}
[root@www ~]# echo $username
      <==因為 username 被設定為空字串了!所以當然還是保留為空字串!
[root@www ~]# username=${username:-root}
[root@www ~]# echo $username
root  <==加上『 : 』後若變數內容為空或者是未設定,都能夠以後面的內容替換!

在大括號內有沒有冒號『 : 』的差別是很大的!加上冒號後,被測試的變數未被設定或者是已被設定為空字串時, 都能夠用後面的內容 (本例中是使用 root 為內容) 來替換與設定!這樣可以瞭解了嗎?除了這樣的測試之外, 還有其他的測試方法喔!鳥哥將他整理如下:

Tips:

底下的例子當中,那個 var 與 str 為變數,我們想要針對 str 是否有設定來決定 var 的值喔! 一般來說, str: 代表『str 沒設定或為空的字串時』;至於 str 則僅為『沒有該變數』。
變數設定方式str 沒有設定str 為空字串str 已設定非為空字串
var=${str-expr}var=exprvar=var=$str
var=${str:-expr}var=exprvar=exprvar=$str
var=${str+expr}var=var=exprvar=expr
var=${str:+expr}var=var=var=expr
var=${str=expr}str=expr
var=expr
str 不變
var=
str 不變
var=$str
var=${str:=expr}str=expr
var=expr
str=expr
var=expr
str 不變
var=$str
var=${str?expr}expr 輸出至 stderrvar=var=$str
var=${str:?expr}expr 輸出至 stderrexpr 輸出至 stderrvar=$str


參考來源:

沒有留言:

張貼留言