bash 的字元串和數組

  • 2019 年 12 月 4 日
  • 筆記

本文作者:IMWeb 江源 原文出處:IMWeb社區 未經同意,禁止轉載

原文

回顧下自己接觸過的程式語言,字元串數組真是基礎中的基礎。也因此,在接觸一門新的語言的時候,非常有必要去熟悉該語言的字元串數組

字元串

聲明和賦值

name='jero' # 單引號  hellojero="hello, $name" # 雙引號,可以引用變數

再看看複雜點的操作。

表達式

含義

${var}

變數 var 的值,與 $var 相同

${var-DEFAULT}

如果 var 沒有被聲明,那麼就以 $DEFAULT 作為其值

${var:-DEFAULT}

如果 var 沒有被聲明, 或者其值為空, 那麼就以 $DEFAULT 作為其值

${var=DEFAULT}

如果 var 沒有被聲明,那麼就以 $DEFAULT 作為其值

${var:=DEFAULT}

如果 var 沒有被聲明, 或者其值為空, 那麼就以 $DEFAULT 作為其值

${var+OTHER}

如果 var 聲明了, 那麼其值就是 $OTHER, 否則就為 null 字元串

${var:+OTHER}

如果 var 被設置了, 那麼其值就是 $OTHER, 否則就為 null 字元串

${var?ERR_MSG}

如果 var 沒被聲明, 那麼就列印 $ERR_MSG

${var:?ERR_MSG}

如果 var 沒被設置, 那麼就列印 $ERR_MSG

${!varprefix*}

匹配之前所有以 varprefix 開頭進行聲明的變數

${!varprefix@}

同上

${var:-DEFAULT} vs ${var:=DEFAULT}

這兩個真的非常像,那麼它們的區別是什麼呢?

foo1=${bar1:-'abc'}  echo $foo1; # abc  echo $bar1; # 空    foo2=${bar2:='abc'}  echo $foo2; # abc  echo $bar2; # abc    # 區別很明顯了,bar1 沒有賦值, bar2 被賦值了

操作

長度

echo ${#name} #4    # 有些資料上會有如下方式:  echo `expr length "$name"`  # 在 mac(10.11.4) 上,會 `syntax error`  # 這是因為 GUN 的 expr 和 BSD 的 expr 有很大的不同,用的時候一定要慎重  # 具體可參考 https://discussions.apple.com/thread/923299    # 可做如下嘗試:  echo `expr "$name" : '.*'` # 4

拼接

拼接就比較靈活了,但不外乎如下幾種方式。

hei="hei, $name" # 利用雙引號  family='jiang'  echo "$hei $family" # hei, jero jiang  echo $hei $family # 當然也可以不用雙引號,但是可讀性降低了

子字元串

表達式

含義

${#string}

$string 的長度

${string:position}

在 $string 中, 從位置 $position 開始提取子串

${string:position:length}

在 $string 中, 從位置 $position 開始提取長度為 $length 的子串

${string#substring}

從變數 $string 的開頭, 刪除最短匹配 $substring 的子串

${string##substring}

從變數 $string 的開頭, 刪除最長匹配 $substring 的子串

${string%substring}

從變數 $string 的結尾, 刪除最短匹配 $substring 的子串

${string%%substring}

從變數 $string 的結尾, 刪除最長匹配 $substring 的子串

${string/substring/replacement}

使用 $replacement, 來代替第一個匹配的 $substring

${string//substring/replacement}

使用 $replacement, 代替所有匹配的 $substring

${string/#substring/replacement}

如果 $string 的前面數位匹配 $substring, 那麼就用 $replacement 來代替匹配到的 $substring

${string/%substring/replacement}

如果 $string 的後面數位匹配 $substring, 那麼就用 $replacement 來代替匹配到的 $substring

substring 可以是正則。

下面來個實例。

long='123456789abcdefg123456789abcdefg123456789'  echo ${#long} # 41,長度  echo ${long:3} # 456789abcdefg123456789abcdefg123456789,從第三位開始截取  echo ${long:3:6} # 456789,從第三位開始截取長度為 6 的子串  echo ${long#*a} # bcdefg123456789abcdefg123456789,從頭刪除最短匹配  echo ${long##*a} # bcdefg123456789,從頭刪除最長匹配  echo ${long%a*} # 123456789abcdefg123456789,從尾開始刪除最短匹配  echo ${long%%a*} # 123456789,從尾開始刪除最長匹配  echo ${long/abc/ABC} # 123456789ABCdefg123456789abcdefg123456789,替換首次出現的子字元串  echo ${long//abc/ABC} # 123456789ABCdefg123456789ABCdefg123456789,全局替換  echo ${long/#123/ABC} # ABC456789abcdefg123456789abcdefg123456789,字元串的前面數位和 123 匹配,替換之  echo ${long/%789/ABC} # 123456789abcdefg123456789abcdefg123456ABC,字元串的後面數位和 789 匹配,替換之

數組

bash 支援一維數組,下標從 0 開始。

declare -a array_name # 聲明一個數組,但並沒人這麼用    arr1=(value0 value1 value2 value3 value)  # 或者  arr1=(      value0      value1      value2      value3      value4  ) # !!!元素之間沒有逗號      # 數組元素不用連續  arr2[0]=v0,  arr2[100]=v100    # 取數組元素,必須用大括弧模式  echo ${arr1[3]} # value2  echo ${arr2[100]} # v100    # 使用 `@` 或 `*` 可以獲取數組中的所有元素  echo ${arr1[*]} # value0 value1 value2 value3 value4  echo ${arr2[@]} # v1 v100    # 獲取數組的長度  echo ${#arr1[*]} # 5  echo ${#arr2[@]} # 2

參考文章