Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
syntax:arrays [2013/06/19 22:22]
ormaaj [Bugs] Bugs fixed.
syntax:arrays [2018/08/22 06:51] (current)
ebersphi
Line 49: Line 49:
 |''​declare -a ARRAY''​ |Declares an **indexed** array ''​ARRAY''​. An existing array is not initialized. | |''​declare -a ARRAY''​ |Declares an **indexed** array ''​ARRAY''​. An existing array is not initialized. |
 |''​declare -A ARRAY''​ |Declares an **associative** array ''​ARRAY''​. This is the one and only way to create associative arrays. | |''​declare -A ARRAY''​ |Declares an **associative** array ''​ARRAY''​. This is the one and only way to create associative arrays. |
 +
 +As an example, and for use below, let's declare our ''​NAMES''​ array as described [[#​purpose|above]]:​
 +
 +    declare -a NAMES=('​Peter'​ '​Anna'​ '​Greg'​ '​Jan'​)
  
 ==== Storing values ==== ==== Storing values ====
Line 54: Line 58:
 Storing values in arrays is quite as simple as storing values in normal variables. Storing values in arrays is quite as simple as storing values in normal variables.
  
-^Syntax ^Description ^ +^ Syntax ​                            ​^ Description ​                                                                                                                                                                                                                                                                                                                                                                                                                                              ​
-|''​ARRAY[N]=VALUE''​ |Sets the element ''​N''​ of the **indexed** array ''​ARRAY''​ to ''​VALUE''​. **''​N''​ can be any valid [[syntax:​arith_expr | arithmetic expression]]**. | +| ''​ARRAY[N]=VALUE'' ​                ​| Sets the element ''​N''​ of the **indexed** array ''​ARRAY''​ to ''​VALUE''​. **''​N''​ can be any valid [[syntax:​arith_expr| arithmetic expression]]**. ​                                                                                                                                                                                                                                                                                                         
-|''​ARRAY[STRING]=VALUE''​ |Sets the element indexed by ''​STRING''​ of the **associative array** ''​ARRAY''​. | +| ''​ARRAY[STRING]=VALUE'' ​           | Sets the element indexed by ''​STRING''​ of the **associative array** ''​ARRAY''​. ​                                                                                                                                                                                                                                                                                                                                                                           
-|''​ARRAY=VALUE''​ |As above. If no index is given, as a default the zeroth element is set to ''​VALUE''​. Careful, this is even true of associative arrays - there is no error if no key is specified, and the value is assigned to string index "​0"​. | +| ''​ARRAY=VALUE'' ​                   | As above. If no index is given, as a default the zeroth element is set to ''​VALUE''​. Careful, this is even true of associative arrays - there is no error if no key is specified, and the value is assigned to string index "​0"​. ​                                                                                                                                                                                                                         
-|''​ARRAY=(E1\ E2\ ...)''​ | Compound array assignment - sets the whole array ''​ARRAY''​ to the given list of elements indexed sequentially starting at zero. The array is unset before assignment unless the += operator is used. When the list is empty (''​ARRAY=()''​),​ the array will be set to an empty array. This method obviously does not use explicit indexes. An **associative array** can **not** be set like that! Clearing an associative array using ''​ARRAY=()''​ works. | +| ''​ARRAY=(E1\ E2\ ...)'' ​           | Compound array assignment - sets the whole array ''​ARRAY''​ to the given list of elements indexed sequentially starting at zero. The array is unset before assignment unless the += operator is used. When the list is empty (''​ARRAY=()''​),​ the array will be set to an empty array. This method obviously does not use explicit indexes. An **associative array** can **not** be set like that! Clearing an associative array using ''​ARRAY=()''​ works. ​ 
-|''​ARRAY=([X]=E1\ [Y]=E2\ ...)''​ |Compound assignment for indexed arrays with index-value pairs declared individually (here for example ''​X''​ and ''​Y''​). X and Y are arithmetic expressions. This syntax can be combined with the above - elements declared without an explicitly specified index are assigned sequentially starting at either the last element with an explicit index, or zero. | +| ''​ARRAY=([X]=E1\ [Y]=E2\ ...)'' ​   | Compound assignment for indexed arrays with index-value pairs declared individually (here for example ''​X''​ and ''​Y''​). X and Y are arithmetic expressions. This syntax can be combined with the above - elements declared without an explicitly specified index are assigned sequentially starting at either the last element with an explicit index, or zero.                                                                                           ​
-|''​ARRAY=([S1]=E1\ [S2]=E2\ ...)''​ |Individual mass-setting for **associative arrays**. The named indexes (here: ''​S1''​ and ''​S2''​) are strings. | +| ''​ARRAY=([S1]=E1\ [S2]=E2\ ...)'' ​ | Individual mass-setting for **associative arrays**. The named indexes (here: ''​S1''​ and ''​S2''​) are strings. ​                                                                                                                                                                                                                                                                                                                                             
-|''​ARRAY+=(E1\ E2\ ...)''​ |Append to ARRAY. |+| ''​ARRAY+=(E1\ E2\ ...)'' ​          ​| Append to ARRAY. ​                                                                                                                                                                                                                                                                                                                                                                                                                                         | 
 +| ''​ARRAY=("​${ANOTHER_ARRAY[@]}"​)'' ​ | Copy ANOTHER_ARRAY to ARRAY, copying each element. ​                                                                                                                                                                                                                                                                                                                                                                                                       ​|
  
 As of now, arrays can't be exported. As of now, arrays can't be exported.
Line 147: Line 152:
 The method above, walking through an array by just knowing its number of elements, only works for arrays where all elements are set, of course. If one element in the middle is removed, then the calculation is nonsense, because the number of elements doesn'​t correspond to the highest used index anymore (we call them "//​sparse arrays//"​). The method above, walking through an array by just knowing its number of elements, only works for arrays where all elements are set, of course. If one element in the middle is removed, then the calculation is nonsense, because the number of elements doesn'​t correspond to the highest used index anymore (we call them "//​sparse arrays//"​).
  
 +Now, suppose that you want to replace your array ''​sentence''​ with the values in the [[#​purpose|previously-declared array]] ''​NAMES''​ . You might think you could just do
 +
 +<​code>​
 +$ unset sentence ; declare -a sentence=NAMES
 +$ echo ${#​sentence[@]}
 +1
 +# omit calculating max_index as above, and iterate as one-liner
 +$ for ((i = 0; i < ${#​sentence[@]};​ i++)); do  echo "​Element $i: '​${sentence[i]}'"​ ; done
 +Element 0: '​NAMES'​
 +</​code>​
 +
 +Obviously that's wrong. What about
 +
 +<​code>​
 +$ unset sentence ; declare -a sentence=${NAMES}
 +</​code>​
 +
 +? Again, wrong:
 +
 +<​code>​
 +$ echo ${#​sentence[*]}
 +1
 +$ for ((i = 0; i < ${#​sentence[@]};​ i++)); do  echo "​Element $i: '​${sentence[i]}'"​ ; done
 +Element 0: '​Peter'​
 +</​code>​
 +
 +So what's the **right** way? The (slightly ugly) answer is, reuse the enumeration syntax:
 +
 +<​code>​
 +$ unset sentence ; declare -a sentence=("​${NAMES[@]}"​)
 +$ echo ${#​sentence[@]}
 +4
 +$ for ((i = 0; i < ${#​sentence[@]};​ i++)); do  echo "​Element $i: '​${sentence[i]}'"​ ; done
 +Element 0: '​Peter'​
 +Element 1: '​Anna'​
 +Element 2: '​Greg'​
 +Element 3: '​Jan'​
 +</​code>​
  
 ==== Associative (Bash 4) ==== ==== Associative (Bash 4) ====
Line 350: Line 393:
 $ set -x; foo=bar declare arr=( {1..10} ) $ set -x; foo=bar declare arr=( {1..10} )
 + foo=bar + foo=bar
-+ declare 'a=(1)' 'a=(2)' 'a=(3)' 'a=(4)' 'a=(5)'++ declare 'arr=(1)' 'arr=(2)' 'arr=(3)' 'arr=(4)' 'arr=(5)' '​arr=(6)'​ '​arr=(7)'​ '​arr=(8)'​ '​arr=(9)'​ '​arr=(10)'
  
 $ touch xy=foo $ touch xy=foo
 ++ touch xy=foo
 $ declare x[y]=* $ declare x[y]=*
 + declare '​x[y]=*'​ + declare '​x[y]=*'​
Line 359: Line 403:
 + declare xy=foo + declare xy=foo
 </​code>​ Each word (the entire assignment) is subject to globbing and brace expansion. This appears to trigger the same strange expansion mode as ''​let'',​ ''​eval'',​ other declaration commands, and maybe more.  </​code>​ Each word (the entire assignment) is subject to globbing and brace expansion. This appears to trigger the same strange expansion mode as ''​let'',​ ''​eval'',​ other declaration commands, and maybe more. 
-  * Indirection combined with another modifier expands arrays to a single word. <​code>​+  ​* **Fixed in 4.3** Indirection combined with another modifier expands arrays to a single word. <​code>​
 $ a=({a..c}) b=a[@]; printf '<​%s>​ ' "​${!b}";​ echo; printf '<​%s>​ ' "​${!b/​%/​foo}";​ echo $ a=({a..c}) b=a[@]; printf '<​%s>​ ' "​${!b}";​ echo; printf '<​%s>​ ' "​${!b/​%/​foo}";​ echo
 <a> <b> <c> <a> <b> <c>
  • syntax/arrays.1371680556.txt
  • Last modified: 2013/06/19 22:22
  • by ormaaj