📄 arrays.html
字号:
><TD><PRECLASS="PROGRAMLISTING"> 1 # Copying an array. 2 array2=( "${array1[@]}" ) 3 # or 4 array2="${array1[@]}" 5 # 6 # However, this fails with "sparse" arrays, 7 #+ arrays with holes (missing elements) in them, 8 #+ as Jochen DeSmet points out. 9 # ------------------------------------------ 10 array1[0]=0 11 # array1[1] not assigned 12 array1[2]=2 13 array2=( "${array1[@]}" ) # Copy it? 14 15 echo ${array2[0]} # 0 16 echo ${array2[2]} # (null), should be 2 17 # ------------------------------------------ 18 19 20 21 # Adding an element to an array. 22 array=( "${array[@]}" "new element" ) 23 # or 24 array[${#array[*]}]="new element" 25 26 # Thanks, S.C.</PRE></TD></TR></TABLE> </P><P><ANAME="ARRAYINITCS"></A></P><DIVCLASS="TIP"><TABLECLASS="TIP"WIDTH="100%"BORDER="0"><TR><TDWIDTH="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><P><ANAME="ARRAYASSIGN0"></A></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/* ) # All the files in /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 # Note parens: ^ ^ 45 times 46 47 48 echo 49 echo '- - testing: =${array[@]} - -' 50 times 51 declare -a bigThree=${bigOne[@]} 52 # No parentheses this time. 53 times 54 55 # Comparing the numbers shows that the second form, pointed out 56 #+ by Stephane Chazelas, is from three to four times faster. 57 # 58 # As William Park explains: 59 #+ The bigTwo array assigned element by element (because of parentheses), 60 #+ whereas bigThree assigned as a single string. 61 # So, in essence, you have: 62 # bigTwo=( [0]="..." [1]="..." [2]="..." ... ) 63 # bigThree=( [0]="... ... ..." ) 64 # 65 # Verify this by: echo ${bigTwo[0]} 66 # echo ${bigThree[0]} 67 68 69 # I will continue to use the first form in my example descriptions 70 #+ because I think it is a better illustration of what is happening. 71 72 # The reusable portions of my examples will actual contain 73 #+ the second form where appropriate because of the speedup. 74 75 # MSZ: Sorry about that earlier oversight folks. 76 77 78 # Note: 79 # ---- 80 # The "declare -a" statements in lines 31 and 43 81 #+ are not strictly necessary, since it is implicit 82 #+ in the Array=( ... ) assignment form. 83 # However, eliminating these declarations slows down 84 #+ the execution of the following sections of the script. 85 # Try it, and see. 86 87 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><P><ANAME="ARRAYAPPEND0"></A></P><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 - -'
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -