📄 arrays.html
字号:
17 # All elements. 18 19 echo ${arrayZ[@]:1} # two three four five five 20 # All elements following element[0]. 21 22 echo ${arrayZ[@]:1:2} # two three 23 # Only the two elements after element[0]. 24 25 echo "-----------------------" 26 27 # Substring Removal 28 # Removes shortest match from front of string(s), 29 #+ where the substring is a regular expression. 30 31 echo ${arrayZ[@]#f*r} # one two three five five 32 # Applied to all elements of the array. 33 # Matches "four" and removes it. 34 35 # Longest match from front of string(s) 36 echo ${arrayZ[@]##t*e} # one two four five five 37 # Applied to all elements of the array. 38 # Matches "three" and removes it. 39 40 # Shortest match from back of string(s) 41 echo ${arrayZ[@]%h*e} # one two t four five five 42 # Applied to all elements of the array. 43 # Matches "hree" and removes it. 44 45 # Longest match from back of string(s) 46 echo ${arrayZ[@]%%t*e} # one two four five five 47 # Applied to all elements of the array. 48 # Matches "three" and removes it. 49 50 echo "-----------------------" 51 52 # Substring Replacement 53 54 # Replace first occurance of substring with replacement 55 echo ${arrayZ[@]/fiv/XYZ} # one two three four XYZe XYZe 56 # Applied to all elements of the array. 57 58 # Replace all occurances of substring 59 echo ${arrayZ[@]//iv/YY} # one two three four fYYe fYYe 60 # Applied to all elements of the array. 61 62 # Delete all occurances of substring 63 # Not specifing a replacement means 'delete' 64 echo ${arrayZ[@]//fi/} # one two three four ve ve 65 # Applied to all elements of the array. 66 67 # Replace front-end occurances of substring 68 echo ${arrayZ[@]/#fi/XY} # one two three four XYve XYve 69 # Applied to all elements of the array. 70 71 # Replace back-end occurances of substring 72 echo ${arrayZ[@]/%ve/ZZ} # one two three four fiZZ fiZZ 73 # Applied to all elements of the array. 74 75 echo ${arrayZ[@]/%o/XX} # one twXX three four five five 76 # Why? 77 78 echo "-----------------------" 79 80 81 # Before reaching for awk (or anything else) -- 82 # Recall: 83 # $( ... ) is command substitution. 84 # Functions run as a sub-process. 85 # Functions write their output to stdout. 86 # Assignment reads the function's stdout. 87 # The name[@] notation specifies a "for-each" operation. 88 89 newstr() { 90 echo -n "!!!" 91 } 92 93 echo ${arrayZ[@]/%e/$(newstr)} 94 # on!!! two thre!!! four fiv!!! fiv!!! 95 # Q.E.D: The replacement action is an 'assignment.' 96 97 # Accessing the "For-Each" 98 echo ${arrayZ[@]//*/$(newstr optional_arguments)} 99 # Now, if Bash would just pass the matched string as $0 100 #+ to the function being called . . . 101 102 echo 103 104 exit 0</PRE></TD></TR></TABLE><HR></DIV><P><AHREF="commandsub.html#COMMANDSUBREF">Command substitution</A> can construct the individual elements of an array.</P><DIVCLASS="EXAMPLE"><HR><ANAME="SCRIPTARRAY"></A><P><B>Example 26-5. Loading the contents of a script into an array</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # script-array.sh: Loads this script into an array. 3 # Inspired by an e-mail from Chris Martin (thanks!). 4 5 script_contents=( $(cat "$0") ) # Stores contents of this script ($0) 6 #+ in an array. 7 8 for element in $(seq 0 $((${#script_contents[@]} - 1))) 9 do # ${#script_contents[@]} 10 #+ gives number of elements in the array. 11 # 12 # Question: 13 # Why is seq 0 necessary? 14 # Try changing it to seq 1. 15 echo -n "${script_contents[$element]}" 16 # List each field of this script on a single line. 17 echo -n " -- " # Use " -- " as a field separator. 18 done 19 20 echo 21 22 exit 0 23 24 # Exercise: 25 # -------- 26 # Modify this script so it lists itself 27 #+ in its original format, 28 #+ complete with whitespace, line breaks, etc.</PRE></TD></TR></TABLE><HR></DIV><P>In an array context, some Bash <AHREF="internal.html#BUILTINREF">builtins</A> have a slightly altered meaning. <ANAME="ARRAYUNSET"></A>For example, <AHREF="internal.html#UNSETREF">unset</A> deletes array elements, or even an entire array.</P><P><ANAME="ARRAYSPECIALPROPS"></A></P><DIVCLASS="EXAMPLE"><HR><ANAME="EX67"></A><P><B>Example 26-6. Some special properties of arrays</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 declare -a colors 4 # All subsequent commands in this script will treat 5 #+ the variable "colors" as an array. 6 7 echo "Enter your favorite colors (separated from each other by a space)." 8 9 read -a colors # Enter at least 3 colors to demonstrate features below. 10 # Special option to 'read' command, 11 #+ allowing assignment of elements in an array. 12 13 echo 14 15 element_count=${#colors[@]} 16 # Special syntax to extract number of elements in array. 17 # element_count=${#colors[*]} works also. 18 # 19 # The "@" variable allows word splitting within quotes 20 #+ (extracts variables separated by whitespace). 21 # 22 # This corresponds to the behavior of "$@" and "$*" 23 #+ in positional parameters. 24 25 index=0 26 27 while [ "$index" -lt "$element_count" ] 28 do # List all the elements in the array. 29 echo ${colors[$index]} 30 let "index = $index + 1" 31 # Or: 32 # index+=1 33 # if running Bash, version 3.1 or later. 34 done 35 # Each array element listed on a separate line. 36 # If this is not desired, use echo -n "${colors[$index]} " 37 # 38 # Doing it with a "for" loop instead: 39 # for i in "${colors[@]}" 40 # do 41 # echo "$i" 42 # done 43 # (Thanks, S.C.) 44 45 echo 46 47 # Again, list all the elements in the array, but using a more elegant method. 48 echo ${colors[@]} # echo ${colors[*]} also works. 49 50 echo 51 52 # The "unset" command deletes elements of an array, or entire array. 53 unset colors[1] # Remove 2nd element of array. 54 # Same effect as colors[1]= 55 echo ${colors[@]} # List array again, missing 2nd element. 56 57 unset colors # Delete entire array. 58 # unset colors[*] and 59 #+ unset colors[@] also work. 60 echo; echo -n "Colors gone." 61 echo ${colors[@]} # List array again, now empty. 62 63 exit 0</PRE></TD></TR></TABLE><HR></DIV><P><ANAME="ARRAYNUMELEMENTS"></A></P><P>As seen in the previous example, either <BCLASS="COMMAND">${array_name[@]}</B> or <BCLASS="COMMAND">${array_name[*]}</B> refers to <SPANCLASS="emphasis"><ICLASS="EMPHASIS">all</I></SPAN> the elements of the array. Similarly, to get a count of the number of elements in an array, use either <BCLASS="COMMAND">${#array_name[@]}</B> or <BCLASS="COMMAND">${#array_name[*]}</B>. <BCLASS="COMMAND">${#array_name}</B> is the length (number of characters) of <BCLASS="COMMAND">${array_name[0]}</B>, the first element of the array.</P><P><ANAME="EMPTYARRAY0"></A></P><DIVCLASS="EXAMPLE"><HR><ANAME="EMPTYARRAY"></A><P><B>Example 26-7. Of empty arrays and empty elements</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # empty-array.sh 3 4 # Thanks to Stephane Chazelas for the original example, 5 #+ and to Michael Zick and Omair Eshkenazi for extending it. 6 7 8 # An empty array is not the same as an array with empty elements. 9 10 array0=( first second third ) 11 array1=( '' ) # "array1" consists of one empty element. 12 array2=( ) # No elements . . . "array2" is empty. 13 array3=( ) # What about this array? 14 15 echo 16 ListArray() 17 { 18 echo 19 echo "Elements in array0: ${array0[@]}" 20 echo "Elements in array1: ${array1[@]}" 21 echo "Elements in array2: ${array2[@]}" 22 echo "Elements in array3: ${array3[@]}" 23 echo 24 echo "Length of first element in array0 = ${#array0}" 25 echo "Length of first element in array1 = ${#array1}" 26 echo "Length of first element in array2 = ${#array2}" 27 echo "Length of first element in array3 = ${#array3}" 28 echo 29 echo "Number of elements in array0 = ${#array0[*]}" # 3 30 echo "Number of elements in array1 = ${#array1[*]}" # 1 (Surprise!) 31 echo "Number of elements in array2 = ${#array2[*]}" # 0 32 echo "Number of elements in array3 = ${#array3[*]}" # 0 33 } 34 35 # =================================================================== 36 37 ListArray 38 39 # Try extending those arrays. 40 41 # Adding an element to an array. 42 array0=( "${array0[@]}" "new1" ) 43 array1=( "${array1[@]}" "new1" ) 44 array2=( "${array2[@]}" "new1" ) 45 array3=( "${array3[@]}" "new1" ) 46 47 ListArray 48 49 # or 50 array0[${#array0[*]}]="new2" 51 array1[${#array1[*]}]="new2" 52 array2[${#array2[*]}]="new2" 53 array3[${#array3[*]}]="new2" 54 55 ListArray 56 57 # When extended as above; arrays are 'stacks' 58 # The above is the 'push' 59 # The stack 'height' is: 60 height=${#array2[@]} 61 echo 62 echo "Stack height for array2 = $height" 63 64 # The 'pop' is: 65 unset array2[${#array2[@]}-1] # Arrays are zero-based, 66 height=${#array2[@]} #+ which means first element has index 0. 67 echo 68 echo "POP" 69 echo "New stack height for array2 = $height" 70 71 ListArray 72 73 # List only 2nd and 3rd elements of array0. 74 from=1 # Zero-based numbering. 75 to=2 76 array3=( ${array0[@]:1:2} ) 77 echo 78 echo "Elements in array3: ${array3[@]}" 79 80 # Works like a string (array of characters). 81 # Try some other "string" forms. 82 83 # Replacement: 84 array4=( ${array0[@]/second/2nd} ) 85 echo 86 echo "Elements in array4: ${array4[@]}" 87 88 # Replace all matching wildcarded string. 89 array5=( ${array0[@]//new?/old} ) 90 echo 91 echo "Elements in array5: ${array5[@]}" 92 93 # Just when you are getting the feel for this . . . 94 array6=( ${array0[@]#*new} ) 95 echo # This one might surprise you. 96 echo "Elements in array6: ${array6[@]}" 97 98 array7=( ${array0[@]#new1} ) 99 echo # After array6 this should not be a surprise. 100 echo "Elements in array7: ${array7[@]}" 101 102 # Which looks a lot like . . . 103 array8=( ${array0[@]/new1/} ) 104 echo 105 echo "Elements in array8: ${array8[@]}" 106 107 # So what can one say about this? 108 109 # The string operations are performed on 110 #+ each of the elements in var[@] in succession. 111 # Therefore : Bash supports string vector operations 112 #+ if the result is a zero length string, 113 #+ that element disappears in the resulting assignment. 114 115 # Question, are those strings hard or soft quotes? 116 117 zap='new*' 118 array9=( ${array0[@]/$zap/} ) 119 echo 120 echo "Elements in array9: ${array9[@]}" 121 122 # Just when you thought you where still in Kansas . . . 123 array10=( ${array0[@]#$zap} ) 124 echo 125 echo "Elements in array10: ${array10[@]}" 126 127 # Compare array7 with array10. 128 # Compare array8 with array9. 129 130 # Answer: must be soft quotes. 131 132 exit 0</PRE></TD></TR></TABLE><HR></DIV><P>The relationship of <BCLASS="COMMAND">${array_name[@]}</B> and <BCLASS="COMMAND">${array_name[*]}</B> is analogous to that between <AHREF="variables2.html#APPREF">$@ and $*</A>. This powerful array notation has a number of uses.</P><P><ANAME="COPYARRAY0"></A></P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -