Manipulating BASH Variables

BASH 變數值的操作

【摘要】敘述 BASH 變數的處理,包括取用某部分、取代某部分、長度等。


【目錄】

    【前言
    【取用子字串
        【 : :
        【 # ; ##
        【 % ; %%
    【取代子字串
        【 / / ; // /
        【 /# / ; /% /
    【變數長度 #
    【找變數 ! *

【前言】

一、在取用 BASH 變數值時,可以依需要做些變化,譬如:只取某部分,或取代某部分。

二、約兩年半前,本文曾在 Google 的 Blogger 發表過,近日加以修改並新增一些內容,記錄於此。


【取用子字串】

【 : : 】

${變數名:起點:長度}

  起點:開始取用的索引(index),第一個字元的索引是 0
  長度:字元數;若省略,表最長,也就是取到最後

例:

VAR="abcdefg 1234567"
echo ${VAR:3}

顯示:

defg 1234567

  從索引 3(即第 4 字元)開始,到最後

echo ${VAR:(-3)}

顯示:

567

  從倒數第 3 個索引(即倒數第 3 字元)開始,到最後
  小括號是必需的


例:

VAR=1234567890
echo ${VAR:4:4}

顯示:

5678

  從索引 4 開始取 4 個(即從第 5 字元開始取 4 個字元)

echo ${VAR:(-6):4}

顯示:

5678

  從倒數第 6 個字元開始,取 4 個字元


例:

VAR="1234567890"
echo ${VAR:(-6):(-3)}

顯示:

567

  從倒數第 6 個字元開始,取到倒數第 3 字元之前,也就是扣掉 3 個字元

echo ${VAR:6:(-3)}

顯示:

7

  從第 7 字元開始,取到倒數第 3 字元之前,也就是扣掉最後 3 個字元


【 # ; ## 】

${變數名#模式}
  從頭開始找最短的符合字串,將之去掉
${變數名##模式}
  從頭開始找最長的符合字串,將之去掉

  模式:pattern 是指欲去除的部分,剩下的才是結果;可用的特殊字元有:
    ? 一個任何字元
    * 0 到多個任何字元
    [...] 其中任一字元,開頭加 ^ 表非列舉的字元

例:

VAR="wildcard characters"
echo ${VAR#*c}

顯示:

ard characters

  從頭開始,經 0 或任意數字元,到第一個 c

echo ${VAR##*c}

顯示:

ters

  從頭開始,經 0 或任意數字元,到最後一個 c

echo ${VAR#c*}
echo ${VAR##c*}

都顯示:

wildcard characters

  找 c 開頭,加 0 或任意數字元
  因字首是 w 所以找不到符合者

echo ${VAR#*[acd]}

顯示:

card characters

  從頭開始,經 0 或任意數字元,到第一個 a 或 c 或 d

echo ${VAR##*[b-p]}

顯示:

rs

  從頭開始,經 0 或任意數字元,到最後一個 b 到 p 的任一字母


【 % ; %% 】

${變數名%模式}
  從尾開始找最短的符合字串,將之去掉
${變數名%%模式}
  從尾開始找最長的符合字串,將之去掉

  模式:pattern 是指欲去除的部分,剩下的才是結果;可用的特殊字元有:
    ? 一個任何字元
    * 0 到多個任何字元
    [...] 其中任一字元,開頭加 ^ 表非列舉的字元

例:

VAR="wildcard characters"
echo ${VAR%c*}

顯示:

wildcard chara

  從尾開始,經 0 或任意數字元,到最後一個(最右邊的)c

echo ${VAR%%c*}

顯示:

wild

  從尾開始,經 0 或任意數字元,到第一個(最左邊的)c


例:

VAR='/usr/share/doc/bash/README'
echo ${VAR##*/}

顯示:

README

  只取檔名
  / 視為一般字元

echo ${VAR%/*}

顯示:

/usr/share/doc/bash

  檔案所屬資料夾路徑


例:

VAR="https://zh.wikipedia.org/wiki/Bash"

想要只取出網域名,必需掐頭去尾,所以要分兩步驟:

VAR=$(echo ${VAR#*//}) && echo ${VAR%%/*}

VAR=${VAR#*//} && VAR=${VAR%%/*} && echo $VAR

顯示:

zh.wikipedia.org

【取代子字串】

【 / / ; // / 】

${變數名/模式/新字串}
  找到第一個符合模式的子字串後,用新字串取代
${變數名//模式/新字串}
  用新字串取代所有符合模式的子字串

不論是字串還是數字都可以。

如果沒有新字串,即是刪除符合者。其前的斜線可有可無,即 ${變數名/模式/}${變數名/模式} 一樣,都是刪除符合模式者。

例:

echo ${PATH}

顯示:

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

若要逐行列出路徑:

echo -e ${PATH//:/\\n}

顯示:

/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games

【 /# / ; /% / 】

${變數名/#模式/新字串}
  用新字串取代開頭符合模式的子字串
${變數名/%模式/新字串}
  用新字串取代結尾符合模式的子字串

不論是字串還是數字都可以。

如果沒有新字串,即是刪除符合者。其前的斜線可有可無,即 ${變數名/#模式/}${變數名/#模式} 一樣,都是刪除符合模式者。

例:

VAR="123456"
echo ${VAR/#12/abc}
echo ${VAR/#??/abc}

都顯示:

abc3456

例:

VAR=123456
echo ${VAR/%56/abc}

顯示:

1234abc

【變數長度 #】

${#變數名}

  如果變數值是字串,指字元數(含空格)
  若是整數,指位數(含負號)
  若是陣列,是指第一個元素的長度

例:

VAR1="an example"
VAR2=-123
echo ${#VAR1}, ${#VAR2}

顯示:

10, 4

【找變數 ! *】

${!字串*}

  已宣告的變數中,所有開頭符合字串

這裡是字串,不是模式

例:

VAR1="abc"
VAR2=123
echo ${!VAR*}

顯示:

VAR1 VAR2

發表留言