📄 arrays.html
字号:
WIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="common/tip.png"HSPACE="5"ALT="Tip"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>The <BCLASS="COMMAND">array=( element1 element2 ... elementN )</B> initialization operation, with the help of <AHREF="commandsub.html#COMMANDSUBREF">command substitution</A>, makes it possible to load the contents of a text file into an array.</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 filename=sample_file 4 5 # cat sample_file 6 # 7 # 1 a b c 8 # 2 d e fg 9 10 11 declare -a array1 12 13 array1=( `cat "$filename"`) # Loads contents 14 # List file to stdout #+ of $filename into array1. 15 # 16 # array1=( `cat "$filename" | tr '\n' ' '`) 17 # change linefeeds in file to spaces. 18 # Not necessary because Bash does word splitting, 19 #+ changing linefeeds to spaces. 20 21 echo ${array1[@]} # List the array. 22 # 1 a b c 2 d e fg 23 # 24 # Each whitespace-separated "word" in the file 25 #+ has been assigned to an element of the array. 26 27 element_count=${#array1[*]} 28 echo $element_count # 8</PRE></TD></TR></TABLE> </P></TD></TR></TABLE></DIV><P>Clever scripting makes it possible to add array operations.</P><DIVCLASS="EXAMPLE"><HR><ANAME="ARRAYASSIGN"></A><P><B>Example 26-8. Initializing arrays</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #! /bin/bash 2 # array-assign.bash 3 4 # Array operations are Bash specific, 5 #+ hence the ".bash" in the script name. 6 7 # Copyright (c) Michael S. Zick, 2003, All rights reserved. 8 # License: Unrestricted reuse in any form, for any purpose. 9 # Version: $ID$ 10 # 11 # Clarification and additional comments by William Park. 12 13 # Based on an example provided by Stephane Chazelas 14 #+ which appeared in the book: Advanced Bash Scripting Guide. 15 16 # Output format of the 'times' command: 17 # User CPU <space> System CPU 18 # User CPU of dead children <space> System CPU of dead children 19 20 # Bash has two versions of assigning all elements of an array 21 #+ to a new array variable. 22 # Both drop 'null reference' elements 23 #+ in Bash versions 2.04, 2.05a and 2.05b. 24 # An additional array assignment that maintains the relationship of 25 #+ [subscript]=value for arrays may be added to newer versions. 26 27 # Constructs a large array using an internal command, 28 #+ but anything creating an array of several thousand elements 29 #+ will do just fine. 30 31 declare -a bigOne=( /dev/* ) 32 echo 33 echo 'Conditions: Unquoted, default IFS, All-Elements-Of' 34 echo "Number of elements in array is ${#bigOne[@]}" 35 36 # set -vx 37 38 39 40 echo 41 echo '- - testing: =( ${array[@]} ) - -' 42 times 43 declare -a bigTwo=( ${bigOne[@]} ) 44 # ^ ^ 45 times 46 47 echo 48 echo '- - testing: =${array[@]} - -' 49 times 50 declare -a bigThree=${bigOne[@]} 51 # No parentheses this time. 52 times 53 54 # Comparing the numbers shows that the second form, pointed out 55 #+ by Stephane Chazelas, is from three to four times faster. 56 # 57 # William Park explains: 58 #+ The bigTwo array assigned as single string, whereas 59 #+ bigThree assigned element by element. 60 # So, in essence, you have: 61 # bigTwo=( [0]="... ... ..." ) 62 # bigThree=( [0]="..." [1]="..." [2]="..." ... ) 63 64 65 # I will continue to use the first form in my example descriptions 66 #+ because I think it is a better illustration of what is happening. 67 68 # The reusable portions of my examples will actual contain 69 #+ the second form where appropriate because of the speedup. 70 71 # MSZ: Sorry about that earlier oversight folks. 72 73 74 # Note: 75 # ---- 76 # The "declare -a" statements in lines 31 and 43 77 #+ are not strictly necessary, since it is implicit 78 #+ in the Array=( ... ) assignment form. 79 # However, eliminating these declarations slows down 80 #+ the execution of the following sections of the script. 81 # Try it, and see what happens. 82 83 exit 0</PRE></TD></TR></TABLE><HR></DIV><DIVCLASS="NOTE"><TABLECLASS="NOTE"WIDTH="100%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="common/note.png"HSPACE="5"ALT="Note"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>Adding a superfluous <BCLASS="COMMAND">declare -a</B> statement to an array declaration may speed up execution of subsequent operations on the array.</P></TD></TR></TABLE></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="COPYARRAY"></A><P><B>Example 26-9. Copying and concatenating arrays</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #! /bin/bash 2 # CopyArray.sh 3 # 4 # This script written by Michael Zick. 5 # Used here with permission. 6 7 # How-To "Pass by Name & Return by Name" 8 #+ or "Building your own assignment statement". 9 10 11 CpArray_Mac() { 12 13 # Assignment Command Statement Builder 14 15 echo -n 'eval ' 16 echo -n "$2" # Destination name 17 echo -n '=( ${' 18 echo -n "$1" # Source name 19 echo -n '[@]} )' 20 21 # That could all be a single command. 22 # Matter of style only. 23 } 24 25 declare -f CopyArray # Function "Pointer" 26 CopyArray=CpArray_Mac # Statement Builder 27 28 Hype() 29 { 30 31 # Hype the array named $1. 32 # (Splice it together with array containing "Really Rocks".) 33 # Return in array named $2. 34 35 local -a TMP 36 local -a hype=( Really Rocks ) 37 38 $($CopyArray $1 TMP) 39 TMP=( ${TMP[@]} ${hype[@]} ) 40 $($CopyArray TMP $2) 41 } 42 43 declare -a before=( Advanced Bash Scripting ) 44 declare -a after 45 46 echo "Array Before = ${before[@]}" 47 48 Hype before after 49 50 echo "Array After = ${after[@]}" 51 52 # Too much hype? 53 54 echo "What ${after[@]:3:2}?" 55 56 declare -a modest=( ${after[@]:2:1} ${after[@]:3:2} ) 57 # ---- substring extraction ---- 58 59 echo "Array Modest = ${modest[@]}" 60 61 # What happened to 'before' ? 62 63 echo "Array Before = ${before[@]}" 64 65 exit 0</PRE></TD></TR></TABLE><HR></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="ARRAYAPPEND"></A><P><B>Example 26-10. More on concatenating arrays</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #! /bin/bash 2 # array-append.bash 3 4 # Copyright (c) Michael S. Zick, 2003, All rights reserved. 5 # License: Unrestricted reuse in any form, for any purpose. 6 # Version: $ID$ 7 # 8 # Slightly modified in formatting by M.C. 9 10 11 # Array operations are Bash-specific. 12 # Legacy UNIX /bin/sh lacks equivalents. 13 14 15 # Pipe the output of this script to 'more' 16 #+ so it doesn't scroll off the terminal. 17 18 19 # Subscript packed. 20 declare -a array1=( zero1 one1 two1 ) 21 # Subscript sparse ([1] is not defined). 22 declare -a array2=( [0]=zero2 [2]=two2 [3]=three2 ) 23 24 echo 25 echo '- Confirm that the array is really subscript sparse. -' 26 echo "Number of elements: 4" # Hard-coded for illustration. 27 for (( i = 0 ; i < 4 ; i++ )) 28 do 29 echo "Element [$i]: ${array2[$i]}" 30 done 31 # See also the more general code example in basics-reviewed.bash. 32 33 34 declare -a dest 35 36 # Combine (append) two arrays into a third array. 37 echo 38 echo 'Conditions: Unquoted, default IFS, All-Elements-Of operator' 39 echo '- Undefined elements not present, subscripts not maintained. -' 40 # # The undefined elements do not exist; they are not being dropped. 41 42 dest=( ${array1[@]} ${array2[@]} ) 43 # dest=${array1[@]}${array2[@]} # Strange results, possibly a bug. 44 45 # Now, list the result. 46 echo 47 echo '- - Testing Array Append - -' 48 cnt=${#dest[@]} 49 50 echo "Number of elements: $cnt" 51 for (( i = 0 ; i < cnt ; i++ )) 52 do 53 echo "Element [$i]: ${dest[$i]}" 54 done 55 56 # Assign an array to a single array element (twice). 57 dest[0]=${array1[@]} 58 dest[1]=${array2[@]} 59 60 # List the result. 61 echo 62 echo '- - Testing modified array - -' 63 cnt=${#dest[@]} 64 65 echo "Number of elements: $cnt" 66 for (( i = 0 ; i < cnt ; i++ )) 67 do 68 echo "Element [$i]: ${dest[$i]}" 69 done 70 71 # Examine the modified second element. 72 echo 73 echo '- - Reassign and list second element - -' 74 75 declare -a subArray=${dest[1]} 76 cnt=${#subArray[@]} 77 78 echo "Number of elements: $cnt" 79 for (( i = 0 ; i < cnt ; i++ )) 80 do 81 echo "Element [$i]: ${subArray[$i]}" 82 done 83 84 # The assignment of an entire array to a single element 85 #+ of another array using the '=${ ... }' array assignment 86 #+ has converted the array being assigned into a string, 87 #+ with the elements separated by a space (the first character of IFS). 88 89 # If the original elements didn't contain whitespace . . . 90 # If the original array isn't subscript sparse . . . 91 # Then we could get the original array structure back again. 92 93 # Restore from the modified second element. 94 echo 95 echo '- - Listing restored element - -' 96 97 declare -a subArray=( ${dest[1]} ) 98 cnt=${#subArray[@]} 99 100 echo "Number of elements: $cnt" 101 for (( i = 0 ; i < cnt ; i++ )) 102 do 103 echo "Element [$i]: ${subArray[$i]}" 104 done 105 echo '- - Do not depend on this behavior. - -' 106 echo '- - This behavior is subject to change - -' 107 echo '- - in versions of Bash newer than version 2.05b - -' 108 109 # MSZ: Sorry about any earlier confusion folks. 110 111 exit 0</PRE></TD></TR></TABLE><HR></DIV><P>--</P><P>Arrays permit deploying old familiar algorithms as shell scripts. Whether this is necessarily a good idea is left to the reader to decide.</P><DIVCLASS="EXAMPLE"><HR><ANAME="BUBBLE"></A><P><B>Example 26-11. An old friend: <ICLASS="EMPHASIS">The Bubble Sort</I></B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # bubble.sh: Bubble sort, of sorts. 3 4 # Recall the algorithm for a bubble sort. In this particular version...
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -