乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Bash技巧:詳解鍵值對關(guān)聯(lián)數(shù)組、一維索引數(shù)組的用法

       行者花雕 2020-02-16

      Bash 的關(guān)聯(lián)數(shù)組詳解

      Bash 支持關(guān)聯(lián)數(shù)組(associative arrays),可以使用任意的字符串、或者整數(shù)作為下標(biāo)來訪問數(shù)組元素。
      關(guān)聯(lián)數(shù)組的下標(biāo)和值稱為鍵值對,它們是一一對應(yīng)關(guān)系,鍵是唯一的,值可以不唯一。

      要使用關(guān)聯(lián)數(shù)組之前,需要用 declare -A array_name 來進(jìn)行顯式聲明 array_name 變量為關(guān)聯(lián)數(shù)組。

      查看 help declare 對 -A 選項的說明如下:

      -A
      to make NAMEs associative arrays (if supported)

      例如下面的語句定義了一個名為 filetypes 的關(guān)聯(lián)數(shù)組,并為數(shù)組賦值:

      $ declare -A filetypes=([txt]=text [sh]=shell [mk]=makefile)
      $ filetypes[c]="c source file"

      在使用數(shù)組名進(jìn)行賦值時,需要用小括號 () 把所有的值括起來。

      在關(guān)聯(lián)數(shù)組里面,用方括號 [] 括起來的值是 key。
      為方括號 [] 賦予的值是該 key 對應(yīng)的 value。
      不同的鍵值對之間用空格隔開。注意不是用逗號隔開。

      也可以使用 filetypes[key]=value 的方式單獨為指定的關(guān)聯(lián)數(shù)組元素賦值。
      如果所給的 key 之前不存在,bash 會自動創(chuàng)建它。
      如果已經(jīng)存在,則修改它的值為 value 對應(yīng)的值。

      基于前面定義的 filetypes 這個數(shù)組名:

      • ${!filetypes[*]}:獲取關(guān)聯(lián)數(shù)組的所有鍵名,注意在 filetypes 前面有一個感嘆號 ‘!’。

        $ echo ${!filetypes[*]}
        txt sh c mk
      • ${!filetypes[@]}: 獲取關(guān)聯(lián)數(shù)組的所有鍵名。后面會說明使用 *@ 的區(qū)別。

        $ echo ${!filetypes[@]}
        txt sh c mk
      • ${filetypes[*]}:獲取關(guān)聯(lián)數(shù)組的所有值。相比于獲取鍵名的表達(dá)式,少了前面的感嘆號 ‘!’。

        $ echo ${filetypes[*]}
        text shell c source file makefile
      • ${filetypes[@]}:獲取關(guān)聯(lián)數(shù)組的所有值。

        $ echo ${filetypes[@]}
        text shell c source file makefile
      • ${#filetypes[*]}:獲取關(guān)聯(lián)數(shù)組的長度,即元素個數(shù)。注意在 filetypes 前面有一個井號 ‘#’。

        $ echo ${#filetypes[*]}
        4
      • ${#filetypes[@]}:獲取關(guān)聯(lián)數(shù)組的長度,即元素個數(shù)

        $ echo ${#filetypes[@]}
        4
      • ${filetypes[key]}:獲取 key 這個鍵名對應(yīng)的值。注意大括號 {} 是必須的。

        $ echo ${filetypes[sh]}
        shell
        $ echo $filetypes[sh]
        [sh]        # 可以看到,不加大括號時,并不能獲取到數(shù)組元素的值

      查看 man bash 的 Arrays 小節(jié),說明了這幾個表達(dá)式的含義,同時還提到使用 *@ 的區(qū)別,貼出具體的區(qū)別如下:

      If the word is double-quoted, ${name[*]} expands to a single word with the value of each array member separated by the first character of the IFS special variable, and ${name[@]} expands each element of name to a separate word. When there are no array members, ${name[@]} expands to nothing.

      ${!name[@]} and ${!name[*]} expand to the indices assigned in array variable name. The treatment when in double quotes is similar to the expansion of the special parameters @ and * within double quotes.

      即,使用 * 時,如果用雙引號把整個表達(dá)式括起來,例如寫為 "${!name[*]}"、或者 "${name[*]}",那么會把所有值合并成一個字符串。

      使用 @ 時,如果用雙引號把整個表達(dá)式括起來,例如寫為 "${!name[@]}"、或者 "${name[@]}",那么會得到一個字符串?dāng)?shù)組。
      每個數(shù)組元素會用雙引號括起來,所以數(shù)組元素自身的空格不會導(dǎo)致拆分成幾個單詞。

      具體如下面的例子所示,這也是遍歷數(shù)組元素的例子:

      $ for key in "${filetypes[*]}"; do echo "****:" $key; done
      ****: text shell c source file makefile
      $ for key in "${filetypes[@]}"; do echo "@@@@:" $key; done
      @@@@: text
      @@@@: shell
      @@@@: c source file
      @@@@: makefile

      可以看到,"${filetypes[*]}" 只產(chǎn)生一個字符串,for 循環(huán)只遍歷一次。
      "${filetypes[@]}" 產(chǎn)生了多個字符串,for 循環(huán)遍歷多次,是一個字符串?dāng)?shù)組。
      而且所給的 "c source file" 這個字符串沒有被空格隔開成幾個單詞。

      上面的例子也演示了如何用 for 命令來遍歷數(shù)組元素。

      可以使用 declare -p 命令來查看數(shù)組具體的鍵值對關(guān)系:

      $ declare -p filetypes
      declare -A filetypes='([txt]="text" [sh]="shell" [c]="c source file" [mk]="makefile" )'

      Bash 的一維數(shù)組詳解

      Bash 只支持一維數(shù)組 (one-dimensional indexed array),不支持二維數(shù)組。
      聲明一維數(shù)組的方式是:declare -a array_name。
      由于 bash 不要求明確指定變量的類型,其實不聲明也可以,按數(shù)組的方式直接賦值給變量即可。

      查看 help declare 對 -a 選項的說明如下:

      -a
      to make NAMEs indexed arrays (if supported)

      使用 declare -a 聲明的數(shù)組,默認(rèn)以數(shù)字作為數(shù)組下標(biāo),而且不需要指定數(shù)組長度。
      其賦值方式說明如下:

      • array=(value1 value2 value3 ... valueN):這種方式從數(shù)組下標(biāo) 0 開始為數(shù)組元素賦值,不同值之間用空格隔開,所給的值可以是數(shù)字、字符串等。

        $ declare -a array=(1 2 "30" "40" 5)
        $ echo ${array[@]}
        1 2 30 40 5
      • array=([0]=var1 [1]=var2 [2]=var3 ... [n]=varN):這種方式顯式提供數(shù)組下標(biāo),指定為該元素賦值,所給的數(shù)組下標(biāo)可以不連續(xù)。

        $ declare -a array=([0]=1 [1]=2 [3]="30" [6]="60" [9]=9)
        $ echo ${array[@]}    # 用 ${array[@]} 獲取所有數(shù)組元素的值
        1 2 30 60 9
        $ echo ${array[5]}    # 上面賦值的時候,跳過了數(shù)組下標(biāo) 5,所以它對應(yīng)的值為空
        
        $ declare -p array    # 使用 declare -p 命令查看,會打印出被賦值的所有元素
        declare -a array='([0]="1" [1]="2" [3]="30" [6]="60" [9]="9")'
      • array[0]=value1; array[1]=value2; ...; array[n]=varN:這種方式是單獨為數(shù)組元素賦值。

        $ unset array; declare -a array
        $ array[0]=0; array[1]=1; array[7]="70"
        $ declare -p array
        declare -a array='([0]="0" [1]="1" [7]="70")'

      一維數(shù)組的其他用法和前面文章介紹的關(guān)聯(lián)數(shù)組用法一樣。
      例如,可以用 ${array[@]} 獲取所有數(shù)組元素的值,用 ${#array[@]} 獲取數(shù)組的元素個數(shù),等等。

      可以參考下面的代碼片段來遍歷一維數(shù)組元素:

      for item in "${array[@]}"; do
          echo $item
      done

      一維數(shù)組通過正整數(shù)來索引數(shù)組元素。
      如果提供負(fù)整數(shù)的下標(biāo)值,那么它具有特殊含義,表示從數(shù)組末尾開始往前索引。
      例如,array[-1] 會索引到數(shù)組的最后一個元素,array[-2] 索引到數(shù)組的倒數(shù)第二個元素,依此類推。

      具體舉例說明如下:

      $ declare -a array=([0]=0 [1]=1 [2]="20" [3]=3)
      $ echo ${array[-1]}, ${array[-3]}
      3, 1

      注意:雖然 declare -a 聲明的數(shù)組要用數(shù)字作為數(shù)組下標(biāo),但是使用字符串作為數(shù)組下標(biāo)并不會報錯。
      實際測試有一些比較古怪的地方。具體舉例如下:

      $ declare -a array=([0]=0 [1]=1 [2]="20" [3]=3)
      $ array[index]=1000
      $ echo ${array[index]}
      1000
      $ array[new]=2000
      $ echo ${array[index]}
      2000
      $ echo ${array[new]}
      2000
      $ declare -p array
      declare -a array='([0]="2000" [1]="1" [2]="20" [3]="3")'

      可以看到,為 array[index] 元素賦值,沒有報錯,使用 ${array[index]} 可以正常獲取到它的值。
      但是為 array[new] 賦值為 2000 后,使用 ${array[index]} 打印 index 這個字符串下標(biāo)對應(yīng)的數(shù)組元素值,發(fā)現(xiàn)變成了 2000,跟 ${array[new]} 打印的值一樣。
      看起來,就像是這兩個字符串下標(biāo)關(guān)連到同一個數(shù)組元素。

      實際上,它們都對應(yīng)到數(shù)組元素 0。可以看到,上面的 declare -p array 命令打印出 [0] 這個元素值變成了 2000。

      查看 man bash 的 Arrays 部分,說明如下:

      Indexed arrays are referenced using integers (including arithmetic expressions) and are zero-based;

      An indexed array is created automatically if any variable is assigned to using the syntax name[subscript]=value.
      The subscript is treated as an arithmetic expression that must evaluate to a number.

      Referencing an array variable without a subscript is equivalent to referencing the array with a subscript of 0.

      即,indexed array 的下標(biāo)一定是數(shù)字、或者是經(jīng)過算術(shù)表達(dá)式 (arithmetic expressions) 計算得到的數(shù)字。
      如果沒有提供數(shù)組下標(biāo),默認(rèn)會使用數(shù)組下標(biāo) 0。

      由于 bash 的算術(shù)表達(dá)式在獲取變量值時,不需要使用 $ 符號,所以上面的 array[index] 實際上相當(dāng)于 array[$index],也就是獲取 index 變量的值來作為數(shù)組下標(biāo)。

      如果所給的 index 變量沒有值,就相當(dāng)于沒有提供數(shù)組下標(biāo),默認(rèn)使用數(shù)組下標(biāo) 0,所以為 array[index] 賦值,實際上是為 array[0] 賦值。
      同理,為 array[new] 賦值,也是為 array[0] 賦值,會看到 array[index] 的值也跟著改變。

      如果 index 變量的值不是 0,而且 new 變量沒有值,那么為 array[index] 賦值,將不會影響到 array[new]。

      在上面例子的基礎(chǔ)上,繼續(xù)執(zhí)行下面語句:

      $ index=1
      $ array[index]=100
      $ echo "array[index] = ${array[index]}, array[1] = ${array[1]}"
      array[index] = 100, array[1] = 100
      $ array[new]=900
      $ echo "array[new] = ${array[new]}, array[0] = ${array[0]}, array[index]=${array[index]}"
      array[new] = 900, array[0] = 900, array[index]=100
      $ recurse=index
      $ array[recurse]=500
      $ echo "array[index] = ${array[index]}, array[recurse] = ${array[recurse]}, array[1] = ${array[1]}"
      array[index] = 500, array[recurse] = 500, array[1] = 500

      可以看到,將 index 變量賦值為 1,修改 array[index] 的值,則改變的是數(shù)組下標(biāo) 1 對應(yīng)的元素、也就是 array[1] 的值。
      即相當(dāng)于用 $index 獲取該變量的值來作為數(shù)組下標(biāo)。
      此時,由于沒有為 new 變量賦值,修改 array[new] 的值還是關(guān)連到 array[0],不會影響到 array[index]

      如果將變量賦值為字符串,那么會往下遞歸獲取該字符串對應(yīng)的變量值。
      上面將 recurse 賦值為 "index" 字符串,修改 array[recurse] 的值,可以看到 array[1] 的值被改變了。
      即相當(dāng)于先用 $recurse 獲取 recurse 變量的值是 "index",發(fā)現(xiàn)是字符串,繼續(xù)把 "index" 字符串作為變量名。
      $index 來獲取 index 變量的值是 1,最終使用 1 作為數(shù)組下標(biāo)。

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多