📄 arrays.html
字号:
52 # 子串替换 53 54 # 第一个匹配到的子串将会被替换 55 echo ${arrayZ[@]/fiv/XYZ} # one two three four XYZe XYZe 56 # 匹配将应用于数组的所有元素. 57 58 # 所有匹配到的子串都会被替换 59 echo ${arrayZ[@]//iv/YY} # one two three four fYYe fYYe 60 # 匹配将应用于数组的所有元素. 61 62 # 删除所有的匹配子串 63 # 如果没有指定替换字符串的话, 那就意味着'删除' 64 echo ${arrayZ[@]//fi/} # one two three four ve ve 65 # 匹配将应用于数组的所有元素. 66 67 # 替换字符串前端子串 68 echo ${arrayZ[@]/#fi/XY} # one two three four XYve XYve 69 # 匹配将应用于数组的所有元素. 70 71 # 替换字符串后端子串 72 echo ${arrayZ[@]/%ve/ZZ} # one two three four fiZZ fiZZ 73 # 匹配将应用于数组的所有元素. 74 75 echo ${arrayZ[@]/%o/XX} # one twXX three four five five 76 # 为什么? 77 78 echo "-----------------------" 79 80 81 # 在将处理后的结果发送到awk(或者其他的处理工具)之前 -- 82 # 回忆一下: 83 # $( ... )是命令替换. 84 # 函数作为子进程运行. 85 # 函数结果输出到stdout. 86 # 用read来读取函数的stdout. 87 # 使用name[@]表示法指定了一个"for-each"操作. 88 89 newstr() { 90 echo -n "!!!" 91 } 92 93 echo ${arrayZ[@]/%e/$(newstr)} 94 # on!!! two thre!!! four fiv!!! fiv!!! 95 # Q.E.D: 替换动作实际上是一个'赋值'. 96 97 # 使用"For-Each"形式的 98 echo ${arrayZ[@]//*/$(newstr optional_arguments)} 99 # 现在, 如果Bash只将匹配到的子串作为$0100 #+ 传递给将被调用的函数 . . .101 102 echo103 104 exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV><P><AHREF="commandsub.html#COMMANDSUBREF">命令替换</A>可以构造数组的独立元素. (译者注: 换句话说, 就是命令替换也能够给数组赋值.) </P><DIVCLASS="EXAMPLE"><HR><ANAME="SCRIPTARRAY"></A><P><B>例子 26-5. 将脚本的内容赋值给数组</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # script-array.sh: 将这个脚本的内容赋值给数组. 3 # 这个脚本的灵感来自于Chris Martin的e-mail(感谢!). 4 5 script_contents=( $(cat "$0") ) # 将这个脚本的内容($0) 6 #+ 赋值给数组. 7 8 for element in $(seq 0 $((${#script_contents[@]} - 1))) 9 do # ${#script_contents[@]} 10 #+ 表示数组元素的个数. 11 # 12 # 一个小问题: 13 # 为什么必须使用seq 0? 14 # 用seq 1来试一下. 15 echo -n "${script_contents[$element]}" 16 # 在同一行上显示脚本中每个域的内容. 17 echo -n " -- " # 使用 " -- " 作为域分割符. 18 done 19 20 echo 21 22 exit 0 23 24 # 练习: 25 # ----- 26 # 修改这个脚本, 27 #+ 让这个脚本能够按照它原本的格式输出, 28 #+ 连同空白, 换行, 等等. </PRE></FONT></TD></TR></TABLE><HR></DIV><P>在数组环境中, 某些Bash<AHREF="internal.html#BUILTINREF">内建命令</A>的含义可能会有些轻微的改变. 比如, <AHREF="internal.html#UNSETREF">unset</A>命令可以删除数组元素, 甚至能够删除整个数组. </P><DIVCLASS="EXAMPLE"><HR><ANAME="EX67"></A><P><B>例子 26-6. 一些数组专用的小道具</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 declare -a colors 4 # 脚本中所有的后续命令都会把 5 #+ 变量"colors"看作数组. 6 7 echo "Enter your favorite colors (separated from each other by a space)." 8 9 read -a colors # 至少需要键入3种颜色, 以便于后边的演示. 10 # 'read'命令的特殊选项, 11 #+ 允许给数组元素赋值. 12 13 echo 14 15 element_count=${#colors[@]} 16 # 提取数组元素个数的特殊语法. 17 # 用element_count=${#colors[*]}也一样. 18 # 19 # "@"变量允许在引用中存在单词分割(word splitting) 20 #+ (依靠空白字符来分隔变量). 21 # 22 # 这就好像"$@"和"$*" 23 #+ 在位置参数中的所表现出来的行为一样. 24 25 index=0 26 27 while [ "$index" -lt "$element_count" ] 28 do # 列出数组中的所有元素. 29 echo ${colors[$index]} 30 let "index = $index + 1" 31 # 或: 32 # index+=1 33 # 如果你运行的Bash版本是3.1以后的话, 才支持这种语法. 34 done 35 # 每个数组元素被列为单独的一行. 36 # 如果没有这种要求的话, 可以使用echo -n "${colors[$index]} " 37 # 38 # 也可以使用"for"循环来做: 39 # for i in "${colors[@]}" 40 # do 41 # echo "$i" 42 # done 43 # (感谢, S.C.) 44 45 echo 46 47 # 再次列出数组中的所有元素, 不过这次的做法更优雅. 48 echo ${colors[@]} # 用echo ${colors[*]}也行. 49 50 echo 51 52 # "unset"命令即可以删除数组数据, 也可以删除整个数组. 53 unset colors[1] # 删除数组的第2个元素. 54 # 作用等效于 colors[1]= 55 echo ${colors[@]} # 再次列出数组内容, 第2个元素没了. 56 57 unset colors # 删除整个数组. 58 # unset colors[*] 或 59 #+ unset colors[@] 都可以. 60 echo; echo -n "Colors gone." 61 echo ${colors[@]} # 再次列出数组内容, 内容为空. 62 63 exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV><P>正如我们在前面例子中所看到的, <BCLASS="COMMAND">${array_name[@]}</B>或<BCLASS="COMMAND">${array_name[*]}</B>都与数组中的<EM>所有</EM>元素相关. 同样的, 为了计算数组的元素个数, 可以使用<BCLASS="COMMAND">${#array_name[@]}</B>或<BCLASS="COMMAND">${#array_name[*]}</B>. <BCLASS="COMMAND">${#array_name}</B>是数组第一个元素的长度, 也就是<BCLASS="COMMAND">${array_name[0]}</B>的长度(字符个数). </P><DIVCLASS="EXAMPLE"><HR><ANAME="EMPTYARRAY"></A><P><B>例子 26-7. 空数组与包含空元素的数组</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # empty-array.sh 3 4 # 感谢Stephane Chazelas制作这个例子的原始版本, 5 #+ 同时感谢Michael Zick对这个例子所作的扩展. 6 7 8 # 空数组与包含有空元素的数组, 这两个概念不同. 9 10 array0=( first second third ) 11 array1=( '' ) # "array1"包含一个空元素. 12 array2=( ) # 没有元素 . . . "array2"为空. 13 14 echo 15 ListArray() 16 { 17 echo 18 echo "Elements in array0: ${array0[@]}" 19 echo "Elements in array1: ${array1[@]}" 20 echo "Elements in array2: ${array2[@]}" 21 echo 22 echo "Length of first element in array0 = ${#array0}" 23 echo "Length of first element in array1 = ${#array1}" 24 echo "Length of first element in array2 = ${#array2}" 25 echo 26 echo "Number of elements in array0 = ${#array0[*]}" # 3 27 echo "Number of elements in array1 = ${#array1[*]}" # 1 (惊奇!) 28 echo "Number of elements in array2 = ${#array2[*]}" # 0 29 } 30 31 # =================================================================== 32 33 ListArray 34 35 # 尝试扩展这些数组. 36 37 # 添加一个元素到这个数组. 38 array0=( "${array0[@]}" "new1" ) 39 array1=( "${array1[@]}" "new1" ) 40 array2=( "${array2[@]}" "new1" ) 41 42 ListArray 43 44 # 或 45 array0[${#array0[*]}]="new2" 46 array1[${#array1[*]}]="new2" 47 array2[${#array2[*]}]="new2" 48 49 ListArray 50 51 # 如果你按照上边的方法对数组进行扩展的话; 数组比较象'栈' 52 # 上边的操作就是'压栈' 53 # 栈'高'为: 54 height=${#array2[@]} 55 echo 56 echo "Stack height for array2 = $height" 57 58 # '出栈'就是: 59 unset array2[${#array2[@]}-1] # 数组从0开始索引, 60 height=${#array2[@]} #+ 这意味着第一个数组下标为0. 61 echo 62 echo "POP" 63 echo "New stack height for array2 = $height" 64 65 ListArray 66 67 # 只列出数组array0的第二个和第三个元素. 68 from=1 # 从0开始索引. 69 to=2 # 70 array3=( ${array0[@]:1:2} ) 71 echo 72 echo "Elements in array3: ${array3[@]}" 73 74 # 处理方式就像是字符串(字符数组). 75 # 试试其他的"字符串"形式. 76 77 # 替换: 78 array4=( ${array0[@]/second/2nd} ) 79 echo 80 echo "Elements in array4: ${array4[@]}" 81 82 # 替换掉所有匹配通配符的字符串. 83 array5=( ${array0[@]//new?/old} ) 84 echo 85 echo "Elements in array5: ${array5[@]}" 86 87 # 当你开始觉得对此有把握的时候 . . . 88 array6=( ${array0[@]#*new} ) 89 echo # 这个可能会让你感到惊奇. 90 echo "Elements in array6: ${array6[@]}" 91 92 array7=( ${array0[@]#new1} ) 93 echo # 数组array6之后就没有惊奇了. 94 echo "Elements in array7: ${array7[@]}" 95 96 # 看起来非常像 . . . 97 array8=( ${array0[@]/new1/} ) 98 echo 99 echo "Elements in array8: ${array8[@]}"100 101 # 所以, 让我们怎么形容呢? 102 103 # 对数组var[@]中的每个元素104 #+ 进行连续的字符串操作. 105 # 因此: 如果结果是长度为0的字符串, 106 #+ Bash支持字符串向量操作, 107 #+ 元素会在结果赋值中消失不见. 108 109 # 一个问题, 这些字符串是强引用还是弱引用? 110 111 zap='new*'112 array9=( ${array0[@]/$zap/} )113 echo114 echo "Elements in array9: ${array9[@]}"115 116 # 当你还在考虑, 你身在Kansas州何处时 . . .117 array10=( ${array0[@]#$zap} )118 echo119 echo "Elements in array10: ${array10[@]}"120 121 # 比较array7和array10. 122 # 比较array8和array9. 123 124 # 答案: 必须是弱引用. 125 126 exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV><P><BCLASS="COMMAND">${array_name[@]}</B>和<BCLASS="COMMAND">${array_name[*]}</B>的关系非常类似于<AHREF="internalvariables.html#APPREF">$@ and $*</A>. 这种数组用法用处非常广泛. </P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 # 复制一个数组. 2 array2=( "${array1[@]}" ) 3 # 或 4 array2="${array1[@]}" 5 # 6 # 然而, 如果在"缺项"数组中使用的话, 将会失败, 7 #+ 也就是说数组中存在空洞(中间的某个元素没赋值), 8 #+ 这个问题由Jochen DeSmet指出. 9 # ------------------------------------------ 10 array1[0]=0 11 # array1[1]没赋值 12 array1[2]=2 13 array2=( "${array1[@]}" ) # 拷贝它? 14 15 echo ${array2[0]} # 0 16 echo ${array2[2]} # (null), 应该是2 17 # ------------------------------------------ 18 19 20 21 # 添加一个元素到数组. 22 array=( "${array[@]}" "new element" ) 23 # 或 24 array[${#array[*]}]="new element" 25 26 # 感谢, S.C.</PRE></FONT></TD></TR></TABLE> </P><DIVCLASS="TIP"><P></P><TABLECLASS="TIP"WIDTH="100%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="./images/tip.gif"HSPACE="5"ALT="Tip"></TD><TD
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -