2011年(3)
分类: Python/Ruby
2011-02-12 15:20:54
The Korn shell and Bash provide a limited array capability (arrays are not a part of the POSIX standard shell). Bash arrays may contain an unlimited number of elements (subject to memory limitations); Korn shell arrays are limited to 4096 elements. Array indexing in both shells starts at zero. An array element is accessed with a subscript, which is an integer-valued expression enclosed inside a pair of brackets. You don't declare the maximum size of a shell array; you simply assign values to elements as you need them. The values that you can assign are the same as for ordinary variables.
$ arr[O]=helloTo retrieve an element from an array, you write the array name followed by the element number, enclosed inside a pair of brackets as before. The entire construct must be enclosed inside a pair of curly braces, which is then preceded by a dollar sign.
$ echo ${array[0]}As you can see from the preceding example, if no subscript is specified, element zero is used.
If you forget the curly braces when performing the substitution, here's what happens:
$ echo $array[1]In the preceding example, the value of array is substituted (hello—the value inside array[0]) and then echoed along with [1]. (Note that because the shell does filename substitution after variable substitution, the shell would attempt to match the pattern hello[1] against the files in your current directory.)
The construct [*] can be used as a subscript to substitute all the elements of the array on the command line, with each element delimited by a single space character.
$ echo ${array[*]}The construct ${#array[*]} can be used to substitute the number of elements in the array array.
$ echo ${#array[*]}Note that the number reported here is the actual number of values stored inside the array, not the largest subscript used to store an element inside the array.
$ array[10]=fooYou can declare an array of integers to the shell simply by giving the array name to typeset -i:
typeset -i dataInteger calculations can be performed on array elements using the ((...)) construct:
$ typeset -i arrayNote that not only can you omit the dollar signs and the curly braces when referencing array elements inside double parentheses, you also can omit them outside when the array is declared to be of integer type. Also note that dollar signs are not needed before variables used in subscript expressions.
The following program, called reverse, reads in up to 4096 lines from standard input and then writes them back out to standard output in reverse order:
$ cat reverseThe first while loop executes as long as 4096 or fewer lines have been read and there is more data to be read from standard input (recall the && described at the end of , "Decisions, Decisions").
The following function, cdh, changes the current directory like cd but uses an array to keep a history of previous directories. It allows the user to list the directory history and change back to any directory in it:
$ cat cdhThe CDHIST array stores each directory visited by cdh, and the first element, CDHIST[0], is initialized with the current directory when the cdh file is run:
$ pwdWhen the cdh file was run, CDHIST[0] was assigned /users/pat, and the cdh function was defined; when cdh /tmp was executed, cdlen was assigned the number of elements in CDHIST (one), and CDHIST[1] was assigned /tmp. The cdh –l caused printf to display each element of CDHIST (on this invocation, cdlen was set to 2, because elements 0 and 1 of CDHIST contained data).
Note that the if statement at the beginning of the function sets $1 to $HOME if no arguments are passed. Let's try that out:
$ cdhWell, it worked, but now /users/pat shows up twice in the list. One of the exercises at the end of this chapter asks you to remedy this.
Okay, the most useful feature of cdh is the –n option, which causes it to change the current directory to the one specified in the list:
$ cdh /usr/spool/uucppublicWe can make cdh replace our cd command by using the fact that alias lookup is performed before built-in commands are executed. So if we create a cd alias to cdh, we can have an enhanced cd. In that case, we have to quote every use of cd in the cdh function to prevent recursion:
$ cat cdhsummarizes the various array constructs in the Korn shell and Bash.
Construct |
Meaning |
---|---|
${array[i]} |
Substitute value of element i |
$array |
Substitute value of first element (array[0]) |
${array[*]} |
Substitute value of all elements |
${#array[*]} |
Substitute number of elements |
array[i]=val |
Store val into array[i] |